about summary refs log tree commit diff
path: root/src/librustdoc/html
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-01-13 00:29:34 +0000
committerbors <bors@rust-lang.org>2022-01-13 00:29:34 +0000
commite916815d21e37af5cd85f9eb67cda155d7129fff (patch)
treef3a0e11f2f7b560154d81fc022308ded90370d4f /src/librustdoc/html
parent124555a69e5f65173ec7840000eb8e953d046740 (diff)
parentef96d573bff12330080d22f12cad96b818ea5da7 (diff)
downloadrust-e916815d21e37af5cd85f9eb67cda155d7129fff.tar.gz
rust-e916815d21e37af5cd85f9eb67cda155d7129fff.zip
Auto merge of #92526 - djc:rustdoc-askama, r=jsha
Migrate rustdoc from Tera to Askama

See #84419.

Should probably get a benchmarking run to verify if it has the intended effect on rustdoc performance.

cc `@jsha` `@jyn514.`
Diffstat (limited to 'src/librustdoc/html')
-rw-r--r--src/librustdoc/html/layout.rs20
-rw-r--r--src/librustdoc/html/render/context.rs12
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/render/print_item.rs17
-rw-r--r--src/librustdoc/html/render/templates.rs20
-rw-r--r--src/librustdoc/html/render/write_shared.rs9
-rw-r--r--src/librustdoc/html/sources.rs1
-rw-r--r--src/librustdoc/html/templates/STYLE.md37
-rw-r--r--src/librustdoc/html/templates/page.html140
-rw-r--r--src/librustdoc/html/templates/print_item.html28
10 files changed, 15 insertions, 270 deletions
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 3d3fa3aaeaa..4ca71ea8684 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -7,9 +7,9 @@ use crate::externalfiles::ExternalHtml;
 use crate::html::format::{Buffer, Print};
 use crate::html::render::{ensure_trailing_slash, StylePath};
 
-use serde::Serialize;
+use askama::Template;
 
-#[derive(Clone, Serialize)]
+#[derive(Clone)]
 crate struct Layout {
     crate logo: String,
     crate favicon: String,
@@ -19,14 +19,10 @@ crate struct Layout {
     /// The given user css file which allow to customize the generated
     /// documentation theme.
     crate css_file_extension: Option<PathBuf>,
-    /// If false, the `select` element to have search filtering by crates on rendered docs
-    /// won't be generated.
-    crate generate_search_filter: bool,
     /// If true, then scrape-examples.js will be included in the output HTML file
     crate scrape_examples_extension: bool,
 }
 
-#[derive(Serialize)]
 crate struct Page<'a> {
     crate title: &'a str,
     crate css_class: &'a str,
@@ -45,7 +41,8 @@ impl<'a> Page<'a> {
     }
 }
 
-#[derive(Serialize)]
+#[derive(Template)]
+#[template(path = "page.html")]
 struct PageLayout<'a> {
     static_root_path: &'a str,
     page: &'a Page<'a>,
@@ -58,7 +55,6 @@ struct PageLayout<'a> {
 }
 
 crate fn render<T: Print, S: Print>(
-    templates: &tera::Tera,
     layout: &Layout,
     page: &Page<'_>,
     sidebar: S,
@@ -76,7 +72,7 @@ crate fn render<T: Print, S: Print>(
     let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version");
     let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
     let sidebar = Buffer::html().to_display(sidebar);
-    let teractx = tera::Context::from_serialize(PageLayout {
+    PageLayout {
         static_root_path,
         page,
         layout,
@@ -85,9 +81,9 @@ crate fn render<T: Print, S: Print>(
         content,
         krate_with_trailing_slash,
         rustdoc_version,
-    })
-    .unwrap();
-    templates.render("page.html", &teractx).unwrap()
+    }
+    .render()
+    .unwrap()
 }
 
 crate fn redirect(url: &str) -> String {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 40453de8405..4f3455a9208 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -15,7 +15,6 @@ use rustc_span::symbol::sym;
 
 use super::print_item::{full_path, item_path, print_item};
 use super::search_index::build_index;
-use super::templates;
 use super::write_shared::write_shared;
 use super::{
     collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
@@ -118,8 +117,6 @@ crate struct SharedContext<'tcx> {
     /// the crate.
     redirections: Option<RefCell<FxHashMap<String, String>>>,
 
-    pub(crate) templates: tera::Tera,
-
     /// Correspondance map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
     crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
@@ -218,11 +215,10 @@ impl<'tcx> Context<'tcx> {
 
         if !self.render_redirect_pages {
             layout::render(
-                &self.shared.templates,
                 &self.shared.layout,
                 &page,
                 |buf: &mut _| print_sidebar(self, it, buf),
-                |buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
+                |buf: &mut _| print_item(self, it, buf, &page),
                 &self.shared.style_files,
             )
         } else {
@@ -391,7 +387,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             extension_css,
             resource_suffix,
             static_root_path,
-            generate_search_filter,
             unstable_features,
             generate_redirect_map,
             show_type_layout,
@@ -421,12 +416,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             default_settings,
             krate: krate.name(tcx).to_string(),
             css_file_extension: extension_css,
-            generate_search_filter,
             scrape_examples_extension: !call_locations.is_empty(),
         };
         let mut issue_tracker_base_url = None;
         let mut include_sources = true;
-        let templates = templates::load()?;
 
         // Crawl the crate attributes looking for attributes which control how we're
         // going to emit HTML
@@ -481,7 +474,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             errors: receiver,
             redirections: if generate_redirect_map { Some(Default::default()) } else { None },
             show_type_layout,
-            templates,
             span_correspondance_map: matches,
             cache,
             call_locations,
@@ -577,7 +569,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         };
         let all = self.shared.all.replace(AllTypes::new());
         let v = layout::render(
-            &self.shared.templates,
             &self.shared.layout,
             &page,
             sidebar,
@@ -599,7 +590,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             .map(StylePath::basename)
             .collect::<Result<_, Error>>()?;
         let v = layout::render(
-            &self.shared.templates,
             &self.shared.layout,
             &page,
             sidebar,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index d63df4e4130..dda74904931 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -31,7 +31,6 @@ mod tests;
 mod context;
 mod print_item;
 mod span_map;
-mod templates;
 mod write_shared;
 
 crate use self::context::*;
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 4f7bb39213b..11426cb6571 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -32,7 +32,7 @@ use crate::html::highlight;
 use crate::html::layout::Page;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 
-use serde::Serialize;
+use askama::Template;
 
 const ITEM_TABLE_OPEN: &str = "<div class=\"item-table\">";
 const ITEM_TABLE_CLOSE: &str = "</div>";
@@ -40,13 +40,13 @@ const ITEM_TABLE_ROW_OPEN: &str = "<div class=\"item-row\">";
 const ITEM_TABLE_ROW_CLOSE: &str = "</div>";
 
 // A component in a `use` path, like `string` in std::string::ToString
-#[derive(Serialize)]
 struct PathComponent<'a> {
     path: String,
     name: &'a str,
 }
 
-#[derive(Serialize)]
+#[derive(Template)]
+#[template(path = "print_item.html")]
 struct ItemVars<'a> {
     page: &'a Page<'a>,
     static_root_path: &'a str,
@@ -58,13 +58,7 @@ struct ItemVars<'a> {
     src_href: Option<&'a str>,
 }
 
-pub(super) fn print_item(
-    cx: &Context<'_>,
-    templates: &tera::Tera,
-    item: &clean::Item,
-    buf: &mut Buffer,
-    page: &Page<'_>,
-) {
+pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
     debug_assert!(!item.is_stripped());
     let typ = match *item.kind {
         clean::ModuleItem(_) => {
@@ -143,8 +137,7 @@ pub(super) fn print_item(
         src_href: src_href.as_deref(),
     };
 
-    let teractx = tera::Context::from_serialize(item_vars).unwrap();
-    let heading = templates.render("print_item.html", &teractx).unwrap();
+    let heading = item_vars.render().unwrap();
     buf.write_str(&heading);
 
     match *item.kind {
diff --git a/src/librustdoc/html/render/templates.rs b/src/librustdoc/html/render/templates.rs
deleted file mode 100644
index d1f18239447..00000000000
--- a/src/librustdoc/html/render/templates.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::error::Error as StdError;
-
-use crate::error::Error;
-
-pub(crate) fn load() -> Result<tera::Tera, Error> {
-    let mut templates = tera::Tera::default();
-
-    macro_rules! include_template {
-        ($file:literal, $fullpath:literal) => {
-            templates.add_raw_template($file, include_str!($fullpath)).map_err(|e| Error {
-                file: $file.into(),
-                error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
-            })?
-        };
-    }
-
-    include_template!("page.html", "../templates/page.html");
-    include_template!("print_item.html", "../templates/print_item.html");
-    Ok(templates)
-}
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 563f4ae7385..2e763dbd8fe 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -494,14 +494,7 @@ pub(super) fn write_shared(
                     })
                     .collect::<String>()
             );
-            let v = layout::render(
-                &cx.shared.templates,
-                &cx.shared.layout,
-                &page,
-                "",
-                content,
-                &cx.shared.style_files,
-            );
+            let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.style_files);
             cx.shared.fs.write(dst, v)?;
         }
     }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 04c2b7a0c9a..bae04f2095a 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -203,7 +203,6 @@ impl SourceCollector<'_, '_> {
             static_extra_scripts: &[&format!("source-script{}", self.cx.shared.resource_suffix)],
         };
         let v = layout::render(
-            &self.cx.shared.templates,
             &self.cx.shared.layout,
             &page,
             "",
diff --git a/src/librustdoc/html/templates/STYLE.md b/src/librustdoc/html/templates/STYLE.md
deleted file mode 100644
index fff65e3b5ff..00000000000
--- a/src/librustdoc/html/templates/STYLE.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Style for Templates
-
-This directory has templates in the [Tera templating language](teradoc), which is very
-similar to [Jinja2](jinjadoc) and [Django](djangodoc) templates, and also to [Askama](askamadoc).
-
-[teradoc]: https://tera.netlify.app/docs/#templates
-[jinjadoc]: https://jinja.palletsprojects.com/en/3.0.x/templates/
-[djangodoc]: https://docs.djangoproject.com/en/3.2/topics/templates/
-[askamadoc]: https://docs.rs/askama/0.10.5/askama/
-
-We want our rendered output to have as little unnecessary whitespace as
-possible, so that pages load quickly. To achieve that we use Tera's
-[whitespace control] features. At the end of most lines, we put an empty comment
-tag with the whitespace control characters: `{#- -#}`. This causes all
-whitespace between the end of the line and the beginning of the next, including
-indentation, to be omitted on render. Sometimes we want to preserve a single
-space. In those cases we put the space at the end of the line, followed by
-`{# -#}`, which is a directive to remove following whitespace but not preceding.
-We also use the whitespace control characters in most instances of tags with
-control flow, for example `{%- if foo -%}`.
-
-[whitespace control]: https://tera.netlify.app/docs/#whitespace-control
-
-We want our templates to be readable, so we use indentation and newlines
-liberally. We indent by four spaces after opening an HTML tag _or_ a Tera
-tag. In most cases an HTML tag should be followed by a newline, but if the
-tag has simple contents and fits with its close tag on a single line, the
-contents don't necessarily need a new line.
-
-Tera templates support quite sophisticated control flow. To keep our templates
-simple and understandable, we use only a subset: `if` and `for`. In particular
-we avoid [assignments in the template logic](assignments) and [Tera
-macros](macros). This also may make things easier if we switch to a different
-Jinja-style template system, like Askama, in the future.
-
-[assignments]: https://tera.netlify.app/docs/#assignments
-[macros]: https://tera.netlify.app/docs/#macros
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
deleted file mode 100644
index 5cade1b1a4c..00000000000
--- a/src/librustdoc/html/templates/page.html
+++ /dev/null
@@ -1,140 +0,0 @@
-<!DOCTYPE html> {#- -#}
-<html lang="en"> {#- -#}
-<head> {#- -#}
-    <meta charset="utf-8"> {#- -#}
-    <meta name="viewport" content="width=device-width, initial-scale=1.0"> {#- -#}
-    <meta name="generator" content="rustdoc"> {#- -#}
-    <meta name="description" content="{{page.description}}"> {#- -#}
-    <meta name="keywords" content="{{page.keywords}}"> {#- -#}
-    <title>{{page.title}}</title> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceSerif4-Regular.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}FiraSans-Regular.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}FiraSans-Medium.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceCodePro-Regular.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceSerif4-Bold.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceCodePro-Semibold.ttf.woff2"> {#- -#}
-    <link rel="stylesheet" type="text/css" {# -#}
-          href="{{static_root_path | safe}}normalize{{page.resource_suffix}}.css"> {#- -#}
-    <link rel="stylesheet" type="text/css" {# -#}
-          href="{{static_root_path | safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
-          id="mainThemeStyle"> {#- -#}
-    {%- for theme in themes -%}
-        <link rel="stylesheet" type="text/css" {# -#}
-            href="{{static_root_path | safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
-        {%- if theme == "light" -%}
-            id="themeStyle"
-        {%- else -%}
-            disabled
-        {%- endif -%}
-        >
-    {%- endfor -%}
-    <script id="default-settings" {# -#}
-      {% for k, v in layout.default_settings %}
-        data-{{k}}="{{v}}"
-      {%- endfor -%}
-    ></script> {#- -#}
-    <script src="{{static_root_path | safe}}storage{{page.resource_suffix}}.js"></script> {#- -#}
-    <script src="{{page.root_path | safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
-    <script defer src="{{static_root_path | safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
-    {%- for script in page.static_extra_scripts -%}
-    <script defer src="{{static_root_path | safe}}{{script}}.js"></script> {#- -#}
-    {% endfor %}
-    {%- if layout.scrape_examples_extension -%}
-    <script defer src="{{page.root_path | safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
-    {%- endif -%}
-    {%- for script in page.extra_scripts -%}
-    <script defer src="{{page.root_path | safe}}{{script}}.js"></script> {#- -#}
-    {% endfor %}
-    <noscript> {#- -#}
-        <link rel="stylesheet" {# -#}
-           href="{{static_root_path | safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
-    </noscript> {#- -#}
-    {%- if layout.css_file_extension -%}
-        <link rel="stylesheet" type="text/css" {# -#}
-            href="{{static_root_path | safe}}theme{{page.resource_suffix}}.css"> {#- -#}
-    {%- endif -%}
-    {%- if layout.favicon -%}
-        <link rel="shortcut icon" href="{{layout.favicon}}"> {#- -#}
-    {%- else -%}
-        <link rel="alternate icon" type="image/png" {# -#}
-            href="{{static_root_path | safe}}favicon-16x16{{page.resource_suffix}}.png"> {#- -#}
-        <link rel="alternate icon" type="image/png" {# -#}
-            href="{{static_root_path | safe}}favicon-32x32{{page.resource_suffix}}.png"> {#- -#}
-        <link rel="icon" type="image/svg+xml" {# -#}
-            href="{{static_root_path | safe}}favicon{{page.resource_suffix}}.svg"> {#- -#}
-    {%- endif -%}
-    {{- layout.external_html.in_header | safe -}}
-</head> {#- -#}
-<body class="rustdoc {{page.css_class}}"> {#- -#}
-    <!--[if lte IE 11]> {#- -#}
-    <div class="warning"> {#- -#}
-        This old browser is unsupported and will most likely display funky things. {#- -#}
-    </div> {#- -#}
-    <![endif]--> {#- -#}
-    {{- layout.external_html.before_content | safe -}}
-    <nav class="sidebar"> {#- -#}
-        <div class="sidebar-menu" role="button">&#9776;</div> {#- -#}
-        <a class="sidebar-logo" href="{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html"> {#- -#}
-            <div class="logo-container"> {#- -#}
-            {%- if layout.logo -%}
-                <img src="{{layout.logo}}" alt="logo"> {#- -#}
-            {%- else -%}
-                <img class="rust-logo" src="{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png" alt="logo"> {#- -#}
-            {%- endif -%}
-            </div>
-        </a> {#- -#}
-        {{- sidebar | safe -}}
-    </nav> {#- -#}
-    <main> {#- -#}
-        <div class="width-limiter"> {#- -#}
-            <div class="sub-container"> {#- -#}
-                <a class="sub-logo-container" href="{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html"> {#- -#}
-                    {%- if layout.logo -%}
-                    <img src="{{layout.logo}}" alt="logo">
-                    {%- else -%}
-                    <img class="rust-logo" src="{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png" alt="logo">
-                    {%- endif -%}
-                </a> {#- -#}
-                <nav class="sub"> {#- -#}
-                    <div class="theme-picker"> {#- -#}
-                        <button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
-                            <img width="18" height="18" alt="Pick another theme!" {# -#}
-                             src="{{static_root_path | safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
-                        </button> {#- -#}
-                        <div id="theme-choices" role="menu"></div> {#- -#}
-                    </div> {#- -#}
-                    <form class="search-form"> {#- -#}
-                        <div class="search-container"> {#- -#}
-                            <div>
-                                <input {# -#}
-                                    class="search-input" {# -#}
-                                    name="search" {# -#}
-                                    autocomplete="off" {# -#}
-                                    spellcheck="false" {# -#}
-                                    placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
-                                    type="search"> {#- -#}
-                            </div> {#- -#}
-                            <button type="button" id="help-button" title="help">?</button> {#- -#}
-                            <a id="settings-menu" href="{{page.root_path | safe}}settings.html" title="settings"> {#- -#}
-                                <img width="18" height="18" alt="Change settings" {# -#}
-                                     src="{{static_root_path | safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
-                            </a> {#- -#}
-                        </div> {#- -#}
-                    </form> {#- -#}
-                </nav> {#- -#}
-            </div> {#- -#}
-            <section id="main-content" class="content">{{- content | safe -}}</section> {#- -#}
-            <section id="search" class="content hidden"></section> {#- -#}
-        </div> {#- -#}
-    </main> {#- -#}
-    {{- layout.external_html.after_content | safe -}}
-    <div id="rustdoc-vars" {# -#}
-         data-root-path="{{page.root_path | safe}}" {# -#}
-         data-current-crate="{{layout.krate}}" {# -#}
-         data-themes="{{themes | join(sep=",") }}" {# -#}
-         data-resource-suffix="{{page.resource_suffix}}" {# -#}
-         data-rustdoc-version="{{rustdoc_version}}" {# -#}
-    > {#- -#}
-    </div>
-</body> {#- -#}
-</html> {#- -#}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
deleted file mode 100644
index 09cd8513a64..00000000000
--- a/src/librustdoc/html/templates/print_item.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<div class="main-heading">
-    <h1 class="fqn"> {#- -#}
-        <span class="in-band"> {#- -#}
-            {{-typ-}}
-            {#- The breadcrumbs of the item path, like std::string -#}
-            {%- for component in path_components -%}
-            <a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
-            {%- endfor -%}
-            <a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
-            <button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
-                <img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
-                    width="19" height="18" {# -#}
-                    alt="Copy item path"> {#- -#}
-            </button> {#- -#}
-        </span> {#- -#}
-    </h1> {#- -#}
-    <span class="out-of-band"> {#- -#}
-        {% if stability_since_raw %}
-        {{- stability_since_raw | safe -}} · 
-        {% endif %}
-        {%- if src_href %}
-        <a class="srclink" href="{{src_href | safe}}" title="goto source code">source</a> ·
-        {% endif -%}
-        <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
-            [<span class="inner">&#x2212;</span>] {#- -#}
-        </a> {#- -#}
-    </span> {#- -#}
-</div>