//! Markdown formatting for rustdoc.
//!
//! This module implements markdown formatting through the pulldown-cmark library.
//!
//! ```
//! #![feature(rustc_private)]
//!
//! extern crate rustc_span;
//!
//! use rustc_span::edition::Edition;
//! use rustdoc::html::markdown::{HeadingOffset, IdMap, Markdown, ErrorCodes};
//!
//! let s = "My *markdown* _text_";
//! let mut id_map = IdMap::new();
//! let md = Markdown {
//!     content: s,
//!     links: &[],
//!     ids: &mut id_map,
//!     error_codes: ErrorCodes::Yes,
//!     edition: Edition::Edition2015,
//!     playground: &None,
//!     heading_offset: HeadingOffset::H2,
//! };
//! let mut html = String::new();
//! md.write_into(&mut html).unwrap();
//! // ... something using html
//! ```

use std::borrow::Cow;
use std::collections::VecDeque;
use std::fmt::{self, Write};
use std::iter::Peekable;
use std::ops::{ControlFlow, Range};
use std::path::PathBuf;
use std::str::{self, CharIndices};
use std::sync::atomic::AtomicUsize;
use std::sync::{Arc, Weak};

use pulldown_cmark::{
    BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Options, Parser, Tag, TagEnd, html,
};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{Diag, DiagMessage};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::TyCtxt;
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
use rustc_resolve::rustdoc::may_be_doc_link;
use rustc_span::edition::Edition;
use rustc_span::{Span, Symbol};
use tracing::{debug, trace};

use crate::clean::RenderedLink;
use crate::doctest;
use crate::doctest::GlobalTestOptions;
use crate::html::escape::{Escape, EscapeBodyText};
use crate::html::highlight;
use crate::html::length_limit::HtmlWithLimit;
use crate::html::render::small_url_encode;
use crate::html::toc::{Toc, TocBuilder};

mod footnotes;
#[cfg(test)]
mod tests;

const MAX_HEADER_LEVEL: u32 = 6;

/// Options for rendering Markdown in summaries (e.g., in search results).
pub(crate) fn summary_opts() -> Options {
    Options::ENABLE_TABLES
        | Options::ENABLE_FOOTNOTES
        | Options::ENABLE_STRIKETHROUGH
        | Options::ENABLE_TASKLISTS
        | Options::ENABLE_SMART_PUNCTUATION
}

#[derive(Debug, Clone, Copy)]
pub enum HeadingOffset {
    H1 = 0,
    H2,
    H3,
    H4,
    H5,
    H6,
}

/// When `to_string` is called, this struct will emit the HTML corresponding to
/// the rendered version of the contained markdown string.
pub struct Markdown<'a> {
    pub content: &'a str,
    /// A list of link replacements.
    pub links: &'a [RenderedLink],
    /// The current list of used header IDs.
    pub ids: &'a mut IdMap,
    /// Whether to allow the use of explicit error codes in doctest lang strings.
    pub error_codes: ErrorCodes,
    /// Default edition to use when parsing doctests (to add a `fn main`).
    pub edition: Edition,
    pub playground: &'a Option<Playground>,
    /// Offset at which we render headings.
    /// E.g. if `heading_offset: HeadingOffset::H2`, then `# something` renders an `<h2>`.
    pub heading_offset: HeadingOffset,
}
/// A struct like `Markdown` that renders the markdown with a table of contents.
pub(crate) struct MarkdownWithToc<'a> {
    pub(crate) content: &'a str,
    pub(crate) links: &'a [RenderedLink],
    pub(crate) ids: &'a mut IdMap,
    pub(crate) error_codes: ErrorCodes,
    pub(crate) edition: Edition,
    pub(crate) playground: &'a Option<Playground>,
}
/// A tuple struct like `Markdown` that renders the markdown escaping HTML tags
/// and includes no paragraph tags.
pub(crate) struct MarkdownItemInfo<'a>(pub(crate) &'a str, pub(crate) &'a mut IdMap);
/// A tuple struct like `Markdown` that renders only the first paragraph.
pub(crate) struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum ErrorCodes {
    Yes,
    No,
}

impl ErrorCodes {
    pub(crate) fn from(b: bool) -> Self {
        match b {
            true => ErrorCodes::Yes,
            false => ErrorCodes::No,
        }
    }

    pub(crate) fn as_bool(self) -> bool {
        match self {
            ErrorCodes::Yes => true,
            ErrorCodes::No => false,
        }
    }
}

/// Controls whether a line will be hidden or shown in HTML output.
///
/// All lines are used in documentation tests.
pub(crate) enum Line<'a> {
    Hidden(&'a str),
    Shown(Cow<'a, str>),
}

impl<'a> Line<'a> {
    fn for_html(self) -> Option<Cow<'a, str>> {
        match self {
            Line::Shown(l) => Some(l),
            Line::Hidden(_) => None,
        }
    }

    pub(crate) fn for_code(self) -> Cow<'a, str> {
        match self {
            Line::Shown(l) => l,
            Line::Hidden(l) => Cow::Borrowed(l),
        }
    }
}

/// This function is used to handle the "hidden lines" (ie starting with `#`) in
/// doctests. It also transforms `##` back into `#`.
// FIXME: There is a minor inconsistency here. For lines that start with ##, we
// have no easy way of removing a potential single space after the hashes, which
// is done in the single # case. This inconsistency seems okay, if non-ideal. In
// order to fix it we'd have to iterate to find the first non-# character, and
// then reallocate to remove it; which would make us return a String.
pub(crate) fn map_line(s: &str) -> Line<'_> {
    let trimmed = s.trim();
    if trimmed.starts_with("##") {
        Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
    } else if let Some(stripped) = trimmed.strip_prefix("# ") {
        // # text
        Line::Hidden(stripped)
    } else if trimmed == "#" {
        // We cannot handle '#text' because it could be #[attr].
        Line::Hidden("")
    } else {
        Line::Shown(Cow::Borrowed(s))
    }
}

/// Convert chars from a title for an id.
///
/// "Hello, world!" -> "hello-world"
fn slugify(c: char) -> Option<char> {
    if c.is_alphanumeric() || c == '-' || c == '_' {
        if c.is_ascii() { Some(c.to_ascii_lowercase()) } else { Some(c) }
    } else if c.is_whitespace() && c.is_ascii() {
        Some('-')
    } else {
        None
    }
}

#[derive(Debug)]
pub struct Playground {
    pub crate_name: Option<Symbol>,
    pub url: String,
}

/// Adds syntax highlighting and playground Run buttons to Rust code blocks.
struct CodeBlocks<'p, 'a, I: Iterator<Item = Event<'a>>> {
    inner: I,
    check_error_codes: ErrorCodes,
    edition: Edition,
    // Information about the playground if a URL has been specified, containing an
    // optional crate name and the URL.
    playground: &'p Option<Playground>,
}

impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
    fn new(
        iter: I,
        error_codes: ErrorCodes,
        edition: Edition,
        playground: &'p Option<Playground>,
    ) -> Self {
        CodeBlocks { inner: iter, check_error_codes: error_codes, edition, playground }
    }
}

impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        let event = self.inner.next();
        let Some(Event::Start(Tag::CodeBlock(kind))) = event else {
            return event;
        };

        let mut original_text = String::new();
        for event in &mut self.inner {
            match event {
                Event::End(TagEnd::CodeBlock) => break,
                Event::Text(ref s) => {
                    original_text.push_str(s);
                }
                _ => {}
            }
        }

        let LangString { added_classes, compile_fail, should_panic, ignore, edition, .. } =
            match kind {
                CodeBlockKind::Fenced(ref lang) => {
                    let parse_result =
                        LangString::parse_without_check(lang, self.check_error_codes);
                    if !parse_result.rust {
                        let added_classes = parse_result.added_classes;
                        let lang_string = if let Some(lang) = parse_result.unknown.first() {
                            format!("language-{lang}")
                        } else {
                            String::new()
                        };
                        let whitespace = if added_classes.is_empty() { "" } else { " " };
                        return Some(Event::Html(
                            format!(
                                "<div class=\"example-wrap\">\
                                 <pre class=\"{lang_string}{whitespace}{added_classes}\">\
                                     <code>{text}</code>\
                                 </pre>\
                             </div>",
                                added_classes = added_classes.join(" "),
                                text = Escape(
                                    original_text.strip_suffix('\n').unwrap_or(&original_text)
                                ),
                            )
                            .into(),
                        ));
                    }
                    parse_result
                }
                CodeBlockKind::Indented => Default::default(),
            };

        let lines = original_text.lines().filter_map(|l| map_line(l).for_html());
        let text = lines.intersperse("\n".into()).collect::<String>();

        let explicit_edition = edition.is_some();
        let edition = edition.unwrap_or(self.edition);

        let playground_button = self.playground.as_ref().and_then(|playground| {
            let krate = &playground.crate_name;
            let url = &playground.url;
            if url.is_empty() {
                return None;
            }
            let test = original_text
                .lines()
                .map(|l| map_line(l).for_code())
                .intersperse("\n".into())
                .collect::<String>();
            let krate = krate.as_ref().map(|s| s.as_str());

            // FIXME: separate out the code to make a code block into runnable code
            //        from the complicated doctest logic
            let opts = GlobalTestOptions {
                crate_name: krate.map(String::from).unwrap_or_default(),
                no_crate_inject: false,
                insert_indent_space: true,
                args_file: PathBuf::new(),
            };
            let mut builder = doctest::BuildDocTestBuilder::new(&test).edition(edition);
            if let Some(krate) = krate {
                builder = builder.crate_name(krate);
            }
            let doctest = builder.build(None);
            let (wrapped, _) = doctest.generate_unique_doctest(&test, false, &opts, krate);
            let test = wrapped.to_string();
            let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };

            let test_escaped = small_url_encode(test);
            Some(format!(
                "<a class=\"test-arrow\" \
                    target=\"_blank\" \
                    title=\"Run code\" \
                    href=\"{url}?code={test_escaped}{channel}&amp;edition={edition}\"></a>",
            ))
        });

        let tooltip = {
            use highlight::Tooltip::*;

            if ignore == Ignore::All {
                Some(IgnoreAll)
            } else if let Ignore::Some(platforms) = ignore {
                Some(IgnoreSome(platforms))
            } else if compile_fail {
                Some(CompileFail)
            } else if should_panic {
                Some(ShouldPanic)
            } else if explicit_edition {
                Some(Edition(edition))
            } else {
                None
            }
        };

        // insert newline to clearly separate it from the
        // previous block so we can shorten the html output
        let s = format!(
            "\n{}",
            highlight::render_example_with_highlighting(
                &text,
                tooltip.as_ref(),
                playground_button.as_deref(),
                &added_classes,
            )
        );
        Some(Event::Html(s.into()))
    }
}

/// Make headings links with anchor IDs and build up TOC.
struct LinkReplacerInner<'a> {
    links: &'a [RenderedLink],
    shortcut_link: Option<&'a RenderedLink>,
}

struct LinkReplacer<'a, I: Iterator<Item = Event<'a>>> {
    iter: I,
    inner: LinkReplacerInner<'a>,
}

impl<'a, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, I> {
    fn new(iter: I, links: &'a [RenderedLink]) -> Self {
        LinkReplacer { iter, inner: { LinkReplacerInner { links, shortcut_link: None } } }
    }
}

// FIXME: Once we have specialized trait impl (for `Iterator` impl on `LinkReplacer`),
// we can remove this type and move back `LinkReplacerInner` fields into `LinkReplacer`.
struct SpannedLinkReplacer<'a, I: Iterator<Item = SpannedEvent<'a>>> {
    iter: I,
    inner: LinkReplacerInner<'a>,
}

impl<'a, I: Iterator<Item = SpannedEvent<'a>>> SpannedLinkReplacer<'a, I> {
    fn new(iter: I, links: &'a [RenderedLink]) -> Self {
        SpannedLinkReplacer { iter, inner: { LinkReplacerInner { links, shortcut_link: None } } }
    }
}

impl<'a> LinkReplacerInner<'a> {
    fn handle_event(&mut self, event: &mut Event<'a>) {
        // Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`).
        match event {
            // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
            // Remove any disambiguator.
            Event::Start(Tag::Link {
                // [fn@f] or [fn@f][]
                link_type: LinkType::ShortcutUnknown | LinkType::CollapsedUnknown,
                dest_url,
                title,
                ..
            }) => {
                debug!("saw start of shortcut link to {dest_url} with title {title}");
                // If this is a shortcut link, it was resolved by the broken_link_callback.
                // So the URL will already be updated properly.
                let link = self.links.iter().find(|&link| *link.href == **dest_url);
                // Since this is an external iterator, we can't replace the inner text just yet.
                // Store that we saw a link so we know to replace it later.
                if let Some(link) = link {
                    trace!("it matched");
                    assert!(self.shortcut_link.is_none(), "shortcut links cannot be nested");
                    self.shortcut_link = Some(link);
                    if title.is_empty() && !link.tooltip.is_empty() {
                        *title = CowStr::Borrowed(link.tooltip.as_ref());
                    }
                }
            }
            // Now that we're done with the shortcut link, don't replace any more text.
            Event::End(TagEnd::Link) if self.shortcut_link.is_some() => {
                debug!("saw end of shortcut link");
                self.shortcut_link = None;
            }
            // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
            // [`fn@f`]
            Event::Code(text) => {
                trace!("saw code {text}");
                if let Some(link) = self.shortcut_link {
                    // NOTE: this only replaces if the code block is the *entire* text.
                    // If only part of the link has code highlighting, the disambiguator will not be removed.
                    // e.g. [fn@`f`]
                    // This is a limitation from `collect_intra_doc_links`: it passes a full link,
                    // and does not distinguish at all between code blocks.
                    // So we could never be sure we weren't replacing too much:
                    // [fn@my_`f`unc] is treated the same as [my_func()] in that pass.
                    //
                    // NOTE: .get(1..len() - 1) is to strip the backticks
                    if let Some(link) = self.links.iter().find(|l| {
                        l.href == link.href
                            && Some(&**text) == l.original_text.get(1..l.original_text.len() - 1)
                    }) {
                        debug!("replacing {text} with {new_text}", new_text = link.new_text);
                        *text = CowStr::Borrowed(&link.new_text);
                    }
                }
            }
            // Replace plain text in links, but only in the middle of a shortcut link.
            // [fn@f]
            Event::Text(text) => {
                trace!("saw text {text}");
                if let Some(link) = self.shortcut_link {
                    // NOTE: same limitations as `Event::Code`
                    if let Some(link) = self
                        .links
                        .iter()
                        .find(|l| l.href == link.href && **text == *l.original_text)
                    {
                        debug!("replacing {text} with {new_text}", new_text = link.new_text);
                        *text = CowStr::Borrowed(&link.new_text);
                    }
                }
            }
            // If this is a link, but not a shortcut link,
            // replace the URL, since the broken_link_callback was not called.
            Event::Start(Tag::Link { dest_url, title, .. }) => {
                if let Some(link) =
                    self.links.iter().find(|&link| *link.original_text == **dest_url)
                {
                    *dest_url = CowStr::Borrowed(link.href.as_ref());
                    if title.is_empty() && !link.tooltip.is_empty() {
                        *title = CowStr::Borrowed(link.tooltip.as_ref());
                    }
                }
            }
            // Anything else couldn't have been a valid Rust path, so no need to replace the text.
            _ => {}
        }
    }
}

impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        let mut event = self.iter.next();
        if let Some(ref mut event) = event {
            self.inner.handle_event(event);
        }
        // Yield the modified event
        event
    }
}

impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for SpannedLinkReplacer<'a, I> {
    type Item = SpannedEvent<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        let (mut event, range) = self.iter.next()?;
        self.inner.handle_event(&mut event);
        // Yield the modified event
        Some((event, range))
    }
}

/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
struct TableWrapper<'a, I: Iterator<Item = Event<'a>>> {
    inner: I,
    stored_events: VecDeque<Event<'a>>,
}

impl<'a, I: Iterator<Item = Event<'a>>> TableWrapper<'a, I> {
    fn new(iter: I) -> Self {
        Self { inner: iter, stored_events: VecDeque::new() }
    }
}

impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(first) = self.stored_events.pop_front() {
            return Some(first);
        }

        let event = self.inner.next()?;

        Some(match event {
            Event::Start(Tag::Table(t)) => {
                self.stored_events.push_back(Event::Start(Tag::Table(t)));
                Event::Html(CowStr::Borrowed("<div>"))
            }
            Event::End(TagEnd::Table) => {
                self.stored_events.push_back(Event::Html(CowStr::Borrowed("</div>")));
                Event::End(TagEnd::Table)
            }
            e => e,
        })
    }
}

type SpannedEvent<'a> = (Event<'a>, Range<usize>);

/// Make headings links with anchor IDs and build up TOC.
struct HeadingLinks<'a, 'b, 'ids, I> {
    inner: I,
    toc: Option<&'b mut TocBuilder>,
    buf: VecDeque<SpannedEvent<'a>>,
    id_map: &'ids mut IdMap,
    heading_offset: HeadingOffset,
}

impl<'b, 'ids, I> HeadingLinks<'_, 'b, 'ids, I> {
    fn new(
        iter: I,
        toc: Option<&'b mut TocBuilder>,
        ids: &'ids mut IdMap,
        heading_offset: HeadingOffset,
    ) -> Self {
        HeadingLinks { inner: iter, toc, buf: VecDeque::new(), id_map: ids, heading_offset }
    }
}

impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for HeadingLinks<'a, '_, '_, I> {
    type Item = SpannedEvent<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(e) = self.buf.pop_front() {
            return Some(e);
        }

        let event = self.inner.next();
        if let Some((Event::Start(Tag::Heading { level, .. }), _)) = event {
            let mut id = String::new();
            for event in &mut self.inner {
                match &event.0 {
                    Event::End(TagEnd::Heading(_)) => break,
                    Event::Text(text) | Event::Code(text) => {
                        id.extend(text.chars().filter_map(slugify));
                        self.buf.push_back(event);
                    }
                    _ => self.buf.push_back(event),
                }
            }
            let id = self.id_map.derive(id);

            if let Some(ref mut builder) = self.toc {
                let mut text_header = String::new();
                plain_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut text_header);
                let mut html_header = String::new();
                html_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut html_header);
                let sec = builder.push(level as u32, text_header, html_header, id.clone());
                self.buf.push_front((Event::Html(format!("{sec} ").into()), 0..0));
            }

            let level =
                std::cmp::min(level as u32 + (self.heading_offset as u32), MAX_HEADER_LEVEL);
            self.buf.push_back((Event::Html(format!("</h{level}>").into()), 0..0));

            let start_tags =
                format!("<h{level} id=\"{id}\"><a class=\"doc-anchor\" href=\"#{id}\">§</a>");
            return Some((Event::Html(start_tags.into()), 0..0));
        }
        event
    }
}

/// Extracts just the first paragraph.
struct SummaryLine<'a, I: Iterator<Item = Event<'a>>> {
    inner: I,
    started: bool,
    depth: u32,
    skipped_tags: u32,
}

impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
    fn new(iter: I) -> Self {
        SummaryLine { inner: iter, started: false, depth: 0, skipped_tags: 0 }
    }
}

fn check_if_allowed_tag(t: &TagEnd) -> bool {
    matches!(
        t,
        TagEnd::Paragraph
            | TagEnd::Emphasis
            | TagEnd::Strong
            | TagEnd::Strikethrough
            | TagEnd::Link
            | TagEnd::BlockQuote
    )
}

fn is_forbidden_tag(t: &TagEnd) -> bool {
    matches!(
        t,
        TagEnd::CodeBlock
            | TagEnd::Table
            | TagEnd::TableHead
            | TagEnd::TableRow
            | TagEnd::TableCell
            | TagEnd::FootnoteDefinition
    )
}

impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.started && self.depth == 0 {
            return None;
        }
        if !self.started {
            self.started = true;
        }
        if let Some(event) = self.inner.next() {
            let mut is_start = true;
            let is_allowed_tag = match event {
                Event::Start(ref c) => {
                    if is_forbidden_tag(&c.to_end()) {
                        self.skipped_tags += 1;
                        return None;
                    }
                    self.depth += 1;
                    check_if_allowed_tag(&c.to_end())
                }
                Event::End(ref c) => {
                    if is_forbidden_tag(c) {
                        self.skipped_tags += 1;
                        return None;
                    }
                    self.depth -= 1;
                    is_start = false;
                    check_if_allowed_tag(c)
                }
                Event::FootnoteReference(_) => {
                    self.skipped_tags += 1;
                    false
                }
                _ => true,
            };
            if !is_allowed_tag {
                self.skipped_tags += 1;
            }
            return if !is_allowed_tag {
                if is_start {
                    Some(Event::Start(Tag::Paragraph))
                } else {
                    Some(Event::End(TagEnd::Paragraph))
                }
            } else {
                Some(event)
            };
        }
        None
    }
}

/// A newtype that represents a relative line number in Markdown.
///
/// In other words, this represents an offset from the first line of Markdown
/// in a doc comment or other source. If the first Markdown line appears on line 32,
/// and the `MdRelLine` is 3, then the absolute line for this one is 35. I.e., it's
/// a zero-based offset.
pub(crate) struct MdRelLine {
    offset: usize,
}

impl MdRelLine {
    /// See struct docs.
    pub(crate) const fn new(offset: usize) -> Self {
        Self { offset }
    }

    /// See struct docs.
    pub(crate) const fn offset(self) -> usize {
        self.offset
    }
}

pub(crate) fn find_testable_code<T: doctest::DocTestVisitor>(
    doc: &str,
    tests: &mut T,
    error_codes: ErrorCodes,
    extra_info: Option<&ExtraInfo<'_>>,
) {
    find_codes(doc, tests, error_codes, extra_info, false)
}

pub(crate) fn find_codes<T: doctest::DocTestVisitor>(
    doc: &str,
    tests: &mut T,
    error_codes: ErrorCodes,
    extra_info: Option<&ExtraInfo<'_>>,
    include_non_rust: bool,
) {
    let mut parser = Parser::new_ext(doc, main_body_opts()).into_offset_iter();
    let mut prev_offset = 0;
    let mut nb_lines = 0;
    let mut register_header = None;
    while let Some((event, offset)) = parser.next() {
        match event {
            Event::Start(Tag::CodeBlock(kind)) => {
                let block_info = match kind {
                    CodeBlockKind::Fenced(ref lang) => {
                        if lang.is_empty() {
                            Default::default()
                        } else {
                            LangString::parse(lang, error_codes, extra_info)
                        }
                    }
                    CodeBlockKind::Indented => Default::default(),
                };
                if !include_non_rust && !block_info.rust {
                    continue;
                }

                let mut test_s = String::new();

                while let Some((Event::Text(s), _)) = parser.next() {
                    test_s.push_str(&s);
                }
                let text = test_s
                    .lines()
                    .map(|l| map_line(l).for_code())
                    .collect::<Vec<Cow<'_, str>>>()
                    .join("\n");

                nb_lines += doc[prev_offset..offset.start].lines().count();
                // If there are characters between the preceding line ending and
                // this code block, `str::lines` will return an additional line,
                // which we subtract here.
                if nb_lines != 0 && !&doc[prev_offset..offset.start].ends_with('\n') {
                    nb_lines -= 1;
                }
                let line = MdRelLine::new(nb_lines);
                tests.visit_test(text, block_info, line);
                prev_offset = offset.start;
            }
            Event::Start(Tag::Heading { level, .. }) => {
                register_header = Some(level as u32);
            }
            Event::Text(ref s) if register_header.is_some() => {
                let level = register_header.unwrap();
                tests.visit_header(s, level);
                register_header = None;
            }
            _ => {}
        }
    }
}

pub(crate) struct ExtraInfo<'tcx> {
    def_id: LocalDefId,
    sp: Span,
    tcx: TyCtxt<'tcx>,
}

impl<'tcx> ExtraInfo<'tcx> {
    pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, sp: Span) -> ExtraInfo<'tcx> {
        ExtraInfo { def_id, sp, tcx }
    }

    fn error_invalid_codeblock_attr(&self, msg: impl Into<DiagMessage>) {
        self.tcx.node_span_lint(
            crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
            self.tcx.local_def_id_to_hir_id(self.def_id),
            self.sp,
            |lint| {
                lint.primary_message(msg);
            },
        );
    }

    fn error_invalid_codeblock_attr_with_help(
        &self,
        msg: impl Into<DiagMessage>,
        f: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
    ) {
        self.tcx.node_span_lint(
            crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
            self.tcx.local_def_id_to_hir_id(self.def_id),
            self.sp,
            |lint| {
                lint.primary_message(msg);
                f(lint);
            },
        );
    }
}

#[derive(Eq, PartialEq, Clone, Debug)]
pub(crate) struct LangString {
    pub(crate) original: String,
    pub(crate) should_panic: bool,
    pub(crate) no_run: bool,
    pub(crate) ignore: Ignore,
    pub(crate) rust: bool,
    pub(crate) test_harness: bool,
    pub(crate) compile_fail: bool,
    pub(crate) standalone_crate: bool,
    pub(crate) error_codes: Vec<String>,
    pub(crate) edition: Option<Edition>,
    pub(crate) added_classes: Vec<String>,
    pub(crate) unknown: Vec<String>,
}

#[derive(Eq, PartialEq, Clone, Debug)]
pub(crate) enum Ignore {
    All,
    None,
    Some(Vec<String>),
}

/// This is the parser for fenced codeblocks attributes. It implements the following eBNF:
///
/// ```eBNF
/// lang-string = *(token-list / delimited-attribute-list / comment)
///
/// bareword = LEADINGCHAR *(CHAR)
/// bareword-without-leading-char = CHAR *(CHAR)
/// quoted-string = QUOTE *(NONQUOTE) QUOTE
/// token = bareword / quoted-string
/// token-without-leading-char = bareword-without-leading-char / quoted-string
/// sep = COMMA/WS *(COMMA/WS)
/// attribute = (DOT token)/(token EQUAL token-without-leading-char)
/// attribute-list = [sep] attribute *(sep attribute) [sep]
/// delimited-attribute-list = OPEN-CURLY-BRACKET attribute-list CLOSE-CURLY-BRACKET
/// token-list = [sep] token *(sep token) [sep]
/// comment = OPEN_PAREN *(all characters) CLOSE_PAREN
///
/// OPEN_PAREN = "("
/// CLOSE_PARENT = ")"
/// OPEN-CURLY-BRACKET = "{"
/// CLOSE-CURLY-BRACKET = "}"
/// LEADINGCHAR = ALPHA | DIGIT | "_" | "-" | ":"
/// ; All ASCII punctuation except comma, quote, equals, backslash, grave (backquote) and braces.
/// ; Comma is used to separate language tokens, so it can't be used in one.
/// ; Quote is used to allow otherwise-disallowed characters in language tokens.
/// ; Equals is used to make key=value pairs in attribute blocks.
/// ; Backslash and grave are special Markdown characters.
/// ; Braces are used to start an attribute block.
/// CHAR = ALPHA | DIGIT | "_" | "-" | ":" | "." | "!" | "#" | "$" | "%" | "&" | "*" | "+" | "/" |
///        ";" | "<" | ">" | "?" | "@" | "^" | "|" | "~"
/// NONQUOTE = %x09 / %x20 / %x21 / %x23-7E ; TAB / SPACE / all printable characters except `"`
/// COMMA = ","
/// DOT = "."
/// EQUAL = "="
///
/// ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
/// DIGIT = %x30-39
/// WS = %x09 / " "
/// ```
pub(crate) struct TagIterator<'a, 'tcx> {
    inner: Peekable<CharIndices<'a>>,
    data: &'a str,
    is_in_attribute_block: bool,
    extra: Option<&'a ExtraInfo<'tcx>>,
    is_error: bool,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum LangStringToken<'a> {
    LangToken(&'a str),
    ClassAttribute(&'a str),
    KeyValueAttribute(&'a str, &'a str),
}

fn is_leading_char(c: char) -> bool {
    c == '_' || c == '-' || c == ':' || c.is_ascii_alphabetic() || c.is_ascii_digit()
}
fn is_bareword_char(c: char) -> bool {
    is_leading_char(c) || ".!#$%&*+/;<>?@^|~".contains(c)
}
fn is_separator(c: char) -> bool {
    c == ' ' || c == ',' || c == '\t'
}

struct Indices {
    start: usize,
    end: usize,
}

impl<'a, 'tcx> TagIterator<'a, 'tcx> {
    pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self {
        Self {
            inner: data.char_indices().peekable(),
            data,
            is_in_attribute_block: false,
            extra,
            is_error: false,
        }
    }

    fn emit_error(&mut self, err: impl Into<DiagMessage>) {
        if let Some(extra) = self.extra {
            extra.error_invalid_codeblock_attr(err);
        }
        self.is_error = true;
    }

    fn skip_separators(&mut self) -> Option<usize> {
        while let Some((pos, c)) = self.inner.peek() {
            if !is_separator(*c) {
                return Some(*pos);
            }
            self.inner.next();
        }
        None
    }

    fn parse_string(&mut self, start: usize) -> Option<Indices> {
        for (pos, c) in self.inner.by_ref() {
            if c == '"' {
                return Some(Indices { start: start + 1, end: pos });
            }
        }
        self.emit_error("unclosed quote string `\"`");
        None
    }

    fn parse_class(&mut self, start: usize) -> Option<LangStringToken<'a>> {
        while let Some((pos, c)) = self.inner.peek().copied() {
            if is_bareword_char(c) {
                self.inner.next();
            } else {
                let class = &self.data[start + 1..pos];
                if class.is_empty() {
                    self.emit_error(format!("unexpected `{c}` character after `.`"));
                    return None;
                } else if self.check_after_token() {
                    return Some(LangStringToken::ClassAttribute(class));
                } else {
                    return None;
                }
            }
        }
        let class = &self.data[start + 1..];
        if class.is_empty() {
            self.emit_error("missing character after `.`");
            None
        } else if self.check_after_token() {
            Some(LangStringToken::ClassAttribute(class))
        } else {
            None
        }
    }

    fn parse_token(&mut self, start: usize) -> Option<Indices> {
        while let Some((pos, c)) = self.inner.peek() {
            if !is_bareword_char(*c) {
                return Some(Indices { start, end: *pos });
            }
            self.inner.next();
        }
        self.emit_error("unexpected end");
        None
    }

    fn parse_key_value(&mut self, c: char, start: usize) -> Option<LangStringToken<'a>> {
        let key_indices =
            if c == '"' { self.parse_string(start)? } else { self.parse_token(start)? };
        if key_indices.start == key_indices.end {
            self.emit_error("unexpected empty string as key");
            return None;
        }

        if let Some((_, c)) = self.inner.next() {
            if c != '=' {
                self.emit_error(format!("expected `=`, found `{c}`"));
                return None;
            }
        } else {
            self.emit_error("unexpected end");
            return None;
        }
        let value_indices = match self.inner.next() {
            Some((pos, '"')) => self.parse_string(pos)?,
            Some((pos, c)) if is_bareword_char(c) => self.parse_token(pos)?,
            Some((_, c)) => {
                self.emit_error(format!("unexpected `{c}` character after `=`"));
                return None;
            }
            None => {
                self.emit_error("expected value after `=`");
                return None;
            }
        };
        if value_indices.start == value_indices.end {
            self.emit_error("unexpected empty string as value");
            None
        } else if self.check_after_token() {
            Some(LangStringToken::KeyValueAttribute(
                &self.data[key_indices.start..key_indices.end],
                &self.data[value_indices.start..value_indices.end],
            ))
        } else {
            None
        }
    }

    /// Returns `false` if an error was emitted.
    fn check_after_token(&mut self) -> bool {
        if let Some((_, c)) = self.inner.peek().copied() {
            if c == '}' || is_separator(c) || c == '(' {
                true
            } else {
                self.emit_error(format!("unexpected `{c}` character"));
                false
            }
        } else {
            // The error will be caught on the next iteration.
            true
        }
    }

    fn parse_in_attribute_block(&mut self) -> Option<LangStringToken<'a>> {
        if let Some((pos, c)) = self.inner.next() {
            if c == '}' {
                self.is_in_attribute_block = false;
                return self.next();
            } else if c == '.' {
                return self.parse_class(pos);
            } else if c == '"' || is_leading_char(c) {
                return self.parse_key_value(c, pos);
            } else {
                self.emit_error(format!("unexpected character `{c}`"));
                return None;
            }
        }
        self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
        None
    }

    /// Returns `false` if an error was emitted.
    fn skip_paren_block(&mut self) -> bool {
        for (_, c) in self.inner.by_ref() {
            if c == ')' {
                return true;
            }
        }
        self.emit_error("unclosed comment: missing `)` at the end");
        false
    }

    fn parse_outside_attribute_block(&mut self, start: usize) -> Option<LangStringToken<'a>> {
        while let Some((pos, c)) = self.inner.next() {
            if c == '"' {
                if pos != start {
                    self.emit_error("expected ` `, `{` or `,` found `\"`");
                    return None;
                }
                let indices = self.parse_string(pos)?;
                if let Some((_, c)) = self.inner.peek().copied()
                    && c != '{'
                    && !is_separator(c)
                    && c != '('
                {
                    self.emit_error(format!("expected ` `, `{{` or `,` after `\"`, found `{c}`"));
                    return None;
                }
                return Some(LangStringToken::LangToken(&self.data[indices.start..indices.end]));
            } else if c == '{' {
                self.is_in_attribute_block = true;
                return self.next();
            } else if is_separator(c) {
                if pos != start {
                    return Some(LangStringToken::LangToken(&self.data[start..pos]));
                }
                return self.next();
            } else if c == '(' {
                if !self.skip_paren_block() {
                    return None;
                }
                if pos != start {
                    return Some(LangStringToken::LangToken(&self.data[start..pos]));
                }
                return self.next();
            } else if (pos == start && is_leading_char(c)) || (pos != start && is_bareword_char(c))
            {
                continue;
            } else {
                self.emit_error(format!("unexpected character `{c}`"));
                return None;
            }
        }
        let token = &self.data[start..];
        if token.is_empty() { None } else { Some(LangStringToken::LangToken(&self.data[start..])) }
    }
}

impl<'a> Iterator for TagIterator<'a, '_> {
    type Item = LangStringToken<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.is_error {
            return None;
        }
        let Some(start) = self.skip_separators() else {
            if self.is_in_attribute_block {
                self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
            }
            return None;
        };
        if self.is_in_attribute_block {
            self.parse_in_attribute_block()
        } else {
            self.parse_outside_attribute_block(start)
        }
    }
}

impl Default for LangString {
    fn default() -> Self {
        Self {
            original: String::new(),
            should_panic: false,
            no_run: false,
            ignore: Ignore::None,
            rust: true,
            test_harness: false,
            compile_fail: false,
            standalone_crate: false,
            error_codes: Vec::new(),
            edition: None,
            added_classes: Vec::new(),
            unknown: Vec::new(),
        }
    }
}

impl LangString {
    fn parse_without_check(string: &str, allow_error_code_check: ErrorCodes) -> Self {
        Self::parse(string, allow_error_code_check, None)
    }

    fn parse(
        string: &str,
        allow_error_code_check: ErrorCodes,
        extra: Option<&ExtraInfo<'_>>,
    ) -> Self {
        let allow_error_code_check = allow_error_code_check.as_bool();
        let mut seen_rust_tags = false;
        let mut seen_other_tags = false;
        let mut seen_custom_tag = false;
        let mut data = LangString::default();
        let mut ignores = vec![];

        data.original = string.to_owned();

        let mut call = |tokens: &mut dyn Iterator<Item = LangStringToken<'_>>| {
            for token in tokens {
                match token {
                    LangStringToken::LangToken("should_panic") => {
                        data.should_panic = true;
                        seen_rust_tags = !seen_other_tags;
                    }
                    LangStringToken::LangToken("no_run") => {
                        data.no_run = true;
                        seen_rust_tags = !seen_other_tags;
                    }
                    LangStringToken::LangToken("ignore") => {
                        data.ignore = Ignore::All;
                        seen_rust_tags = !seen_other_tags;
                    }
                    LangStringToken::LangToken(x)
                        if let Some(ignore) = x.strip_prefix("ignore-") =>
                    {
                        ignores.push(ignore.to_owned());
                        seen_rust_tags = !seen_other_tags;
                    }
                    LangStringToken::LangToken("rust") => {
                        data.rust = true;
                        seen_rust_tags = true;
                    }
                    LangStringToken::LangToken("custom") => {
                        seen_custom_tag = true;
                    }
                    LangStringToken::LangToken("test_harness") => {
                        data.test_harness = true;
                        seen_rust_tags = !seen_other_tags || seen_rust_tags;
                    }
                    LangStringToken::LangToken("compile_fail") => {
                        data.compile_fail = true;
                        seen_rust_tags = !seen_other_tags || seen_rust_tags;
                        data.no_run = true;
                    }
                    LangStringToken::LangToken("standalone_crate") => {
                        data.standalone_crate = true;
                        seen_rust_tags = !seen_other_tags || seen_rust_tags;
                    }
                    LangStringToken::LangToken(x)
                        if let Some(edition) = x.strip_prefix("edition") =>
                    {
                        data.edition = edition.parse::<Edition>().ok();
                    }
                    LangStringToken::LangToken(x)
                        if let Some(edition) = x.strip_prefix("rust")
                            && edition.parse::<Edition>().is_ok()
                            && let Some(extra) = extra =>
                    {
                        extra.error_invalid_codeblock_attr_with_help(
                            format!("unknown attribute `{x}`"),
                            |lint| {
                                lint.help(format!(
                                    "there is an attribute with a similar name: `edition{edition}`"
                                ));
                            },
                        );
                    }
                    LangStringToken::LangToken(x)
                        if allow_error_code_check
                            && let Some(error_code) = x.strip_prefix('E')
                            && error_code.len() == 4 =>
                    {
                        if error_code.parse::<u32>().is_ok() {
                            data.error_codes.push(x.to_owned());
                            seen_rust_tags = !seen_other_tags || seen_rust_tags;
                        } else {
                            seen_other_tags = true;
                        }
                    }
                    LangStringToken::LangToken(x) if let Some(extra) = extra => {
                        if let Some(help) = match x.to_lowercase().as_str() {
                            "compile-fail" | "compile_fail" | "compilefail" => Some(
                                "use `compile_fail` to invert the results of this test, so that it \
                                passes if it cannot be compiled and fails if it can",
                            ),
                            "should-panic" | "should_panic" | "shouldpanic" => Some(
                                "use `should_panic` to invert the results of this test, so that if \
                                passes if it panics and fails if it does not",
                            ),
                            "no-run" | "no_run" | "norun" => Some(
                                "use `no_run` to compile, but not run, the code sample during \
                                testing",
                            ),
                            "test-harness" | "test_harness" | "testharness" => Some(
                                "use `test_harness` to run functions marked `#[test]` instead of a \
                                potentially-implicit `main` function",
                            ),
                            "standalone" | "standalone_crate" | "standalone-crate"
                                if extra.sp.at_least_rust_2024() =>
                            {
                                Some(
                                    "use `standalone_crate` to compile this code block \
                                        separately",
                                )
                            }
                            _ => None,
                        } {
                            extra.error_invalid_codeblock_attr_with_help(
                                format!("unknown attribute `{x}`"),
                                |lint| {
                                    lint.help(help).help(
                                        "this code block may be skipped during testing, \
                                            because unknown attributes are treated as markers for \
                                            code samples written in other programming languages, \
                                            unless it is also explicitly marked as `rust`",
                                    );
                                },
                            );
                        }
                        seen_other_tags = true;
                        data.unknown.push(x.to_owned());
                    }
                    LangStringToken::LangToken(x) => {
                        seen_other_tags = true;
                        data.unknown.push(x.to_owned());
                    }
                    LangStringToken::KeyValueAttribute("class", value) => {
                        data.added_classes.push(value.to_owned());
                    }
                    LangStringToken::KeyValueAttribute(key, ..) if let Some(extra) = extra => {
                        extra
                            .error_invalid_codeblock_attr(format!("unsupported attribute `{key}`"));
                    }
                    LangStringToken::ClassAttribute(class) => {
                        data.added_classes.push(class.to_owned());
                    }
                    _ => {}
                }
            }
        };

        let mut tag_iter = TagIterator::new(string, extra);
        call(&mut tag_iter);

        // ignore-foo overrides ignore
        if !ignores.is_empty() {
            data.ignore = Ignore::Some(ignores);
        }

        data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error;

        data
    }
}

impl<'a> Markdown<'a> {
    pub fn write_into(self, f: impl fmt::Write) -> fmt::Result {
        // This is actually common enough to special-case
        if self.content.is_empty() {
            return Ok(());
        }

        html::write_html_fmt(f, self.into_iter())
    }

    fn into_iter(self) -> CodeBlocks<'a, 'a, impl Iterator<Item = Event<'a>>> {
        let Markdown {
            content: md,
            links,
            ids,
            error_codes: codes,
            edition,
            playground,
            heading_offset,
        } = self;

        let replacer = move |broken_link: BrokenLink<'_>| {
            links
                .iter()
                .find(|link| *link.original_text == *broken_link.reference)
                .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
        };

        let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(replacer));
        let p = p.into_offset_iter();

        ids.handle_footnotes(|ids, existing_footnotes| {
            let p = HeadingLinks::new(p, None, ids, heading_offset);
            let p = SpannedLinkReplacer::new(p, links);
            let p = footnotes::Footnotes::new(p, existing_footnotes);
            let p = TableWrapper::new(p.map(|(ev, _)| ev));
            CodeBlocks::new(p, codes, edition, playground)
        })
    }

    /// Convert markdown to (summary, remaining) HTML.
    ///
    /// - The summary is the first top-level Markdown element (usually a paragraph, but potentially
    ///   any block).
    /// - The remaining docs contain everything after the summary.
    pub(crate) fn split_summary_and_content(self) -> (Option<String>, Option<String>) {
        if self.content.is_empty() {
            return (None, None);
        }
        let mut p = self.into_iter();

        let mut event_level = 0;
        let mut summary_events = Vec::new();
        let mut get_next_tag = false;

        let mut end_of_summary = false;
        while let Some(event) = p.next() {
            match event {
                Event::Start(_) => event_level += 1,
                Event::End(kind) => {
                    event_level -= 1;
                    if event_level == 0 {
                        // We're back at the "top" so it means we're done with the summary.
                        end_of_summary = true;
                        // We surround tables with `<div>` HTML tags so this is a special case.
                        get_next_tag = kind == TagEnd::Table;
                    }
                }
                _ => {}
            }
            summary_events.push(event);
            if end_of_summary {
                if get_next_tag && let Some(event) = p.next() {
                    summary_events.push(event);
                }
                break;
            }
        }
        let mut summary = String::new();
        html::push_html(&mut summary, summary_events.into_iter());
        if summary.is_empty() {
            return (None, None);
        }
        let mut content = String::new();
        html::push_html(&mut content, p);

        if content.is_empty() { (Some(summary), None) } else { (Some(summary), Some(content)) }
    }
}

impl MarkdownWithToc<'_> {
    pub(crate) fn into_parts(self) -> (Toc, String) {
        let MarkdownWithToc { content: md, links, ids, error_codes: codes, edition, playground } =
            self;

        // This is actually common enough to special-case
        if md.is_empty() {
            return (Toc { entries: Vec::new() }, String::new());
        }
        let mut replacer = |broken_link: BrokenLink<'_>| {
            links
                .iter()
                .find(|link| *link.original_text == *broken_link.reference)
                .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
        };

        let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer));
        let p = p.into_offset_iter();

        let mut s = String::with_capacity(md.len() * 3 / 2);

        let mut toc = TocBuilder::new();

        ids.handle_footnotes(|ids, existing_footnotes| {
            let p = HeadingLinks::new(p, Some(&mut toc), ids, HeadingOffset::H1);
            let p = footnotes::Footnotes::new(p, existing_footnotes);
            let p = TableWrapper::new(p.map(|(ev, _)| ev));
            let p = CodeBlocks::new(p, codes, edition, playground);
            html::push_html(&mut s, p);
        });

        (toc.into_toc(), s)
    }

    pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result {
        let (toc, s) = self.into_parts();
        write!(f, "<nav id=\"rustdoc\">{toc}</nav>{s}", toc = toc.print())
    }
}

impl MarkdownItemInfo<'_> {
    pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result {
        let MarkdownItemInfo(md, ids) = self;

        // This is actually common enough to special-case
        if md.is_empty() {
            return Ok(());
        }
        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();

        // Treat inline HTML as plain text.
        let p = p.map(|event| match event.0 {
            Event::Html(text) | Event::InlineHtml(text) => (Event::Text(text), event.1),
            _ => event,
        });

        ids.handle_footnotes(|ids, existing_footnotes| {
            let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1);
            let p = footnotes::Footnotes::new(p, existing_footnotes);
            let p = TableWrapper::new(p.map(|(ev, _)| ev));
            let p = p.filter(|event| {
                !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
            });
            html::write_html_fmt(&mut f, p)
        })
    }
}

impl MarkdownSummaryLine<'_> {
    pub(crate) fn into_string_with_has_more_content(self) -> (String, bool) {
        let MarkdownSummaryLine(md, links) = self;
        // This is actually common enough to special-case
        if md.is_empty() {
            return (String::new(), false);
        }

        let mut replacer = |broken_link: BrokenLink<'_>| {
            links
                .iter()
                .find(|link| *link.original_text == *broken_link.reference)
                .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
        };

        let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer))
            .peekable();
        let mut summary = SummaryLine::new(p);

        let mut s = String::new();

        let without_paragraphs = LinkReplacer::new(&mut summary, links).filter(|event| {
            !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
        });

        html::push_html(&mut s, without_paragraphs);

        let has_more_content =
            matches!(summary.inner.peek(), Some(Event::Start(_))) || summary.skipped_tags > 0;

        (s, has_more_content)
    }

    pub(crate) fn into_string(self) -> String {
        self.into_string_with_has_more_content().0
    }
}

/// Renders a subset of Markdown in the first paragraph of the provided Markdown.
///
/// - *Italics*, **bold**, and `inline code` styles **are** rendered.
/// - Headings and links are stripped (though the text *is* rendered).
/// - HTML, code blocks, and everything else are ignored.
///
/// Returns a tuple of the rendered HTML string and whether the output was shortened
/// due to the provided `length_limit`.
fn markdown_summary_with_limit(
    md: &str,
    link_names: &[RenderedLink],
    length_limit: usize,
) -> (String, bool) {
    if md.is_empty() {
        return (String::new(), false);
    }

    let mut replacer = |broken_link: BrokenLink<'_>| {
        link_names
            .iter()
            .find(|link| *link.original_text == *broken_link.reference)
            .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
    };

    let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
    let mut p = LinkReplacer::new(p, link_names);

    let mut buf = HtmlWithLimit::new(length_limit);
    let mut stopped_early = false;
    let _ = p.try_for_each(|event| {
        match &event {
            Event::Text(text) => {
                let r =
                    text.split_inclusive(char::is_whitespace).try_for_each(|word| buf.push(word));
                if r.is_break() {
                    stopped_early = true;
                }
                return r;
            }
            Event::Code(code) => {
                buf.open_tag("code");
                let r = buf.push(code);
                if r.is_break() {
                    stopped_early = true;
                } else {
                    buf.close_tag();
                }
                return r;
            }
            Event::Start(tag) => match tag {
                Tag::Emphasis => buf.open_tag("em"),
                Tag::Strong => buf.open_tag("strong"),
                Tag::CodeBlock(..) => return ControlFlow::Break(()),
                _ => {}
            },
            Event::End(tag) => match tag {
                TagEnd::Emphasis | TagEnd::Strong => buf.close_tag(),
                TagEnd::Paragraph | TagEnd::Heading(_) => return ControlFlow::Break(()),
                _ => {}
            },
            Event::HardBreak | Event::SoftBreak => buf.push(" ")?,
            _ => {}
        };
        ControlFlow::Continue(())
    });

    (buf.finish(), stopped_early)
}

/// Renders a shortened first paragraph of the given Markdown as a subset of Markdown,
/// making it suitable for contexts like the search index.
///
/// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened.
///
/// See [`markdown_summary_with_limit`] for details about what is rendered and what is not.
pub(crate) fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String {
    let (mut s, was_shortened) = markdown_summary_with_limit(markdown, link_names, 59);

    if was_shortened {
        s.push('…');
    }

    s
}

/// Renders the first paragraph of the provided markdown as plain text.
/// Useful for alt-text.
///
/// - Headings, links, and formatting are stripped.
/// - Inline code is rendered as-is, surrounded by backticks.
/// - HTML and code blocks are ignored.
pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> String {
    if md.is_empty() {
        return String::new();
    }

    let mut s = String::with_capacity(md.len() * 3 / 2);

    let mut replacer = |broken_link: BrokenLink<'_>| {
        link_names
            .iter()
            .find(|link| *link.original_text == *broken_link.reference)
            .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
    };

    let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));

    plain_text_from_events(p, &mut s);

    s
}

pub(crate) fn plain_text_from_events<'a>(
    events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
    s: &mut String,
) {
    for event in events {
        match &event {
            Event::Text(text) => s.push_str(text),
            Event::Code(code) => {
                s.push('`');
                s.push_str(code);
                s.push('`');
            }
            Event::HardBreak | Event::SoftBreak => s.push(' '),
            Event::Start(Tag::CodeBlock(..)) => break,
            Event::End(TagEnd::Paragraph) => break,
            Event::End(TagEnd::Heading(..)) => break,
            _ => (),
        }
    }
}

pub(crate) fn html_text_from_events<'a>(
    events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
    s: &mut String,
) {
    for event in events {
        match &event {
            Event::Text(text) => {
                write!(s, "{}", EscapeBodyText(text)).expect("string alloc infallible")
            }
            Event::Code(code) => {
                s.push_str("<code>");
                write!(s, "{}", EscapeBodyText(code)).expect("string alloc infallible");
                s.push_str("</code>");
            }
            Event::HardBreak | Event::SoftBreak => s.push(' '),
            Event::Start(Tag::CodeBlock(..)) => break,
            Event::End(TagEnd::Paragraph) => break,
            Event::End(TagEnd::Heading(..)) => break,
            _ => (),
        }
    }
}

#[derive(Debug)]
pub(crate) struct MarkdownLink {
    pub kind: LinkType,
    pub link: String,
    pub range: MarkdownLinkRange,
}

#[derive(Clone, Debug)]
pub(crate) enum MarkdownLinkRange {
    /// Normally, markdown link warnings point only at the destination.
    Destination(Range<usize>),
    /// In some cases, it's not possible to point at the destination.
    /// Usually, this happens because backslashes `\\` are used.
    /// When that happens, point at the whole link, and don't provide structured suggestions.
    WholeLink(Range<usize>),
}

impl MarkdownLinkRange {
    /// Extracts the inner range.
    pub fn inner_range(&self) -> &Range<usize> {
        match self {
            MarkdownLinkRange::Destination(range) => range,
            MarkdownLinkRange::WholeLink(range) => range,
        }
    }
}

pub(crate) fn markdown_links<'md, R>(
    md: &'md str,
    preprocess_link: impl Fn(MarkdownLink) -> Option<R>,
) -> Vec<R> {
    use itertools::Itertools;
    if md.is_empty() {
        return vec![];
    }

    // FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
    let locate = |s: &str, fallback: Range<usize>| unsafe {
        let s_start = s.as_ptr();
        let s_end = s_start.add(s.len());
        let md_start = md.as_ptr();
        let md_end = md_start.add(md.len());
        if md_start <= s_start && s_end <= md_end {
            let start = s_start.offset_from(md_start) as usize;
            let end = s_end.offset_from(md_start) as usize;
            MarkdownLinkRange::Destination(start..end)
        } else {
            MarkdownLinkRange::WholeLink(fallback)
        }
    };

    let span_for_link = |link: &CowStr<'_>, span: Range<usize>| {
        // For diagnostics, we want to underline the link's definition but `span` will point at
        // where the link is used. This is a problem for reference-style links, where the definition
        // is separate from the usage.

        match link {
            // `Borrowed` variant means the string (the link's destination) may come directly from
            // the markdown text and we can locate the original link destination.
            // NOTE: LinkReplacer also provides `Borrowed` but possibly from other sources,
            // so `locate()` can fall back to use `span`.
            CowStr::Borrowed(s) => locate(s, span),

            // For anything else, we can only use the provided range.
            CowStr::Boxed(_) | CowStr::Inlined(_) => MarkdownLinkRange::WholeLink(span),
        }
    };

    let span_for_refdef = |link: &CowStr<'_>, span: Range<usize>| {
        // We want to underline the link's definition, but `span` will point at the entire refdef.
        // Skip the label, then try to find the entire URL.
        let mut square_brace_count = 0;
        let mut iter = md.as_bytes()[span.start..span.end].iter().copied().enumerate();
        for (_i, c) in &mut iter {
            match c {
                b':' if square_brace_count == 0 => break,
                b'[' => square_brace_count += 1,
                b']' => square_brace_count -= 1,
                _ => {}
            }
        }
        while let Some((i, c)) = iter.next() {
            if c == b'<' {
                while let Some((j, c)) = iter.next() {
                    match c {
                        b'\\' => {
                            let _ = iter.next();
                        }
                        b'>' => {
                            return MarkdownLinkRange::Destination(
                                i + 1 + span.start..j + span.start,
                            );
                        }
                        _ => {}
                    }
                }
            } else if !c.is_ascii_whitespace() {
                for (j, c) in iter.by_ref() {
                    if c.is_ascii_whitespace() {
                        return MarkdownLinkRange::Destination(i + span.start..j + span.start);
                    }
                }
                return MarkdownLinkRange::Destination(i + span.start..span.end);
            }
        }
        span_for_link(link, span)
    };

    let span_for_offset_backward = |span: Range<usize>, open: u8, close: u8| {
        let mut open_brace = !0;
        let mut close_brace = !0;
        for (i, b) in md.as_bytes()[span.clone()].iter().copied().enumerate().rev() {
            let i = i + span.start;
            if b == close {
                close_brace = i;
                break;
            }
        }
        if close_brace < span.start || close_brace >= span.end {
            return MarkdownLinkRange::WholeLink(span);
        }
        let mut nesting = 1;
        for (i, b) in md.as_bytes()[span.start..close_brace].iter().copied().enumerate().rev() {
            let i = i + span.start;
            if b == close {
                nesting += 1;
            }
            if b == open {
                nesting -= 1;
            }
            if nesting == 0 {
                open_brace = i;
                break;
            }
        }
        assert!(open_brace != close_brace);
        if open_brace < span.start || open_brace >= span.end {
            return MarkdownLinkRange::WholeLink(span);
        }
        // do not actually include braces in the span
        let range = (open_brace + 1)..close_brace;
        MarkdownLinkRange::Destination(range)
    };

    let span_for_offset_forward = |span: Range<usize>, open: u8, close: u8| {
        let mut open_brace = !0;
        let mut close_brace = !0;
        for (i, b) in md.as_bytes()[span.clone()].iter().copied().enumerate() {
            let i = i + span.start;
            if b == open {
                open_brace = i;
                break;
            }
        }
        if open_brace < span.start || open_brace >= span.end {
            return MarkdownLinkRange::WholeLink(span);
        }
        let mut nesting = 0;
        for (i, b) in md.as_bytes()[open_brace..span.end].iter().copied().enumerate() {
            let i = i + open_brace;
            if b == close {
                nesting -= 1;
            }
            if b == open {
                nesting += 1;
            }
            if nesting == 0 {
                close_brace = i;
                break;
            }
        }
        assert!(open_brace != close_brace);
        if open_brace < span.start || open_brace >= span.end {
            return MarkdownLinkRange::WholeLink(span);
        }
        // do not actually include braces in the span
        let range = (open_brace + 1)..close_brace;
        MarkdownLinkRange::Destination(range)
    };

    let mut broken_link_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
    let event_iter = Parser::new_with_broken_link_callback(
        md,
        main_body_opts(),
        Some(&mut broken_link_callback),
    )
    .into_offset_iter();
    let mut links = Vec::new();

    let mut refdefs = FxIndexMap::default();
    for (label, refdef) in event_iter.reference_definitions().iter().sorted_by_key(|x| x.0) {
        refdefs.insert(label.to_string(), (false, refdef.dest.to_string(), refdef.span.clone()));
    }

    for (event, span) in event_iter {
        match event {
            Event::Start(Tag::Link { link_type, dest_url, id, .. })
                if may_be_doc_link(link_type) =>
            {
                let range = match link_type {
                    // Link is pulled from the link itself.
                    LinkType::ReferenceUnknown | LinkType::ShortcutUnknown => {
                        span_for_offset_backward(span, b'[', b']')
                    }
                    LinkType::CollapsedUnknown => span_for_offset_forward(span, b'[', b']'),
                    LinkType::Inline => span_for_offset_backward(span, b'(', b')'),
                    // Link is pulled from elsewhere in the document.
                    LinkType::Reference | LinkType::Collapsed | LinkType::Shortcut => {
                        if let Some((is_used, dest_url, span)) = refdefs.get_mut(&id[..]) {
                            *is_used = true;
                            span_for_refdef(&CowStr::from(&dest_url[..]), span.clone())
                        } else {
                            span_for_link(&dest_url, span)
                        }
                    }
                    LinkType::Autolink | LinkType::Email => unreachable!(),
                };

                if let Some(link) = preprocess_link(MarkdownLink {
                    kind: link_type,
                    link: dest_url.into_string(),
                    range,
                }) {
                    links.push(link);
                }
            }
            _ => {}
        }
    }

    for (_label, (is_used, dest_url, span)) in refdefs.into_iter() {
        if !is_used
            && let Some(link) = preprocess_link(MarkdownLink {
                kind: LinkType::Reference,
                range: span_for_refdef(&CowStr::from(&dest_url[..]), span),
                link: dest_url,
            })
        {
            links.push(link);
        }
    }

    links
}

#[derive(Debug)]
pub(crate) struct RustCodeBlock {
    /// The range in the markdown that the code block occupies. Note that this includes the fences
    /// for fenced code blocks.
    pub(crate) range: Range<usize>,
    /// The range in the markdown that the code within the code block occupies.
    pub(crate) code: Range<usize>,
    pub(crate) is_fenced: bool,
    pub(crate) lang_string: LangString,
}

/// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or
/// untagged (and assumed to be rust).
pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<RustCodeBlock> {
    let mut code_blocks = vec![];

    if md.is_empty() {
        return code_blocks;
    }

    let mut p = Parser::new_ext(md, main_body_opts()).into_offset_iter();

    while let Some((event, offset)) = p.next() {
        if let Event::Start(Tag::CodeBlock(syntax)) = event {
            let (lang_string, code_start, code_end, range, is_fenced) = match syntax {
                CodeBlockKind::Fenced(syntax) => {
                    let syntax = syntax.as_ref();
                    let lang_string = if syntax.is_empty() {
                        Default::default()
                    } else {
                        LangString::parse(syntax, ErrorCodes::Yes, Some(extra_info))
                    };
                    if !lang_string.rust {
                        continue;
                    }
                    let (code_start, mut code_end) = match p.next() {
                        Some((Event::Text(_), offset)) => (offset.start, offset.end),
                        Some((_, sub_offset)) => {
                            let code = Range { start: sub_offset.start, end: sub_offset.start };
                            code_blocks.push(RustCodeBlock {
                                is_fenced: true,
                                range: offset,
                                code,
                                lang_string,
                            });
                            continue;
                        }
                        None => {
                            let code = Range { start: offset.end, end: offset.end };
                            code_blocks.push(RustCodeBlock {
                                is_fenced: true,
                                range: offset,
                                code,
                                lang_string,
                            });
                            continue;
                        }
                    };
                    while let Some((Event::Text(_), offset)) = p.next() {
                        code_end = offset.end;
                    }
                    (lang_string, code_start, code_end, offset, true)
                }
                CodeBlockKind::Indented => {
                    // The ending of the offset goes too far sometime so we reduce it by one in
                    // these cases.
                    if offset.end > offset.start && md.get(offset.end..=offset.end) == Some("\n") {
                        (
                            LangString::default(),
                            offset.start,
                            offset.end,
                            Range { start: offset.start, end: offset.end - 1 },
                            false,
                        )
                    } else {
                        (LangString::default(), offset.start, offset.end, offset, false)
                    }
                }
            };

            code_blocks.push(RustCodeBlock {
                is_fenced,
                range,
                code: Range { start: code_start, end: code_end },
                lang_string,
            });
        }
    }

    code_blocks
}

#[derive(Clone, Default, Debug)]
pub struct IdMap {
    map: FxHashMap<String, usize>,
    existing_footnotes: Arc<AtomicUsize>,
}

fn is_default_id(id: &str) -> bool {
    matches!(
        id,
        // This is the list of IDs used in JavaScript.
        "help"
        | "settings"
        | "not-displayed"
        | "alternative-display"
        | "search"
        | "crate-search"
        | "crate-search-div"
        // This is the list of IDs used in HTML generated in Rust (including the ones
        // used in tera template files).
        | "themeStyle"
        | "settings-menu"
        | "help-button"
        | "sidebar-button"
        | "main-content"
        | "toggle-all-docs"
        | "all-types"
        | "default-settings"
        | "sidebar-vars"
        | "copy-path"
        | "rustdoc-toc"
        | "rustdoc-modnav"
        // This is the list of IDs used by rustdoc sections (but still generated by
        // rustdoc).
        | "fields"
        | "variants"
        | "implementors-list"
        | "synthetic-implementors-list"
        | "foreign-impls"
        | "implementations"
        | "trait-implementations"
        | "synthetic-implementations"
        | "blanket-implementations"
        | "required-associated-types"
        | "provided-associated-types"
        | "provided-associated-consts"
        | "required-associated-consts"
        | "required-methods"
        | "provided-methods"
        | "dyn-compatibility"
        | "implementors"
        | "synthetic-implementors"
        | "implementations-list"
        | "trait-implementations-list"
        | "synthetic-implementations-list"
        | "blanket-implementations-list"
        | "deref-methods"
        | "layout"
        | "aliased-type"
    )
}

impl IdMap {
    pub fn new() -> Self {
        IdMap { map: FxHashMap::default(), existing_footnotes: Arc::new(AtomicUsize::new(0)) }
    }

    pub(crate) fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String {
        let id = match self.map.get_mut(candidate.as_ref()) {
            None => {
                let candidate = candidate.to_string();
                if is_default_id(&candidate) {
                    let id = format!("{}-{}", candidate, 1);
                    self.map.insert(candidate, 2);
                    id
                } else {
                    candidate
                }
            }
            Some(a) => {
                let id = format!("{}-{}", candidate.as_ref(), *a);
                *a += 1;
                id
            }
        };

        self.map.insert(id.clone(), 1);
        id
    }

    /// Method to handle `existing_footnotes` increment automatically (to prevent forgetting
    /// about it).
    pub(crate) fn handle_footnotes<'a, T, F: FnOnce(&'a mut Self, Weak<AtomicUsize>) -> T>(
        &'a mut self,
        closure: F,
    ) -> T {
        let existing_footnotes = Arc::downgrade(&self.existing_footnotes);

        closure(self, existing_footnotes)
    }

    pub(crate) fn clear(&mut self) {
        self.map.clear();
        self.existing_footnotes = Arc::new(AtomicUsize::new(0));
    }
}
