|
17 | 17 | //! // ... something using html
|
18 | 18 | //! ```
|
19 | 19 |
|
20 |
| -#![allow(non_camel_case_types)] |
21 |
| - |
22 | 20 | use rustc_data_structures::fx::FxHashMap;
|
23 | 21 | use rustc_hir::def_id::DefId;
|
24 | 22 | use rustc_hir::HirId;
|
@@ -1037,7 +1035,95 @@ impl MarkdownSummaryLine<'_> {
|
1037 | 1035 | }
|
1038 | 1036 | }
|
1039 | 1037 |
|
| 1038 | +/// Renders a subset of Markdown in the first paragraph of the provided Markdown. |
| 1039 | +/// |
| 1040 | +/// - *Italics*, **bold**, and `inline code` styles **are** rendered. |
| 1041 | +/// - Headings and links are stripped (though the text *is* rendered). |
| 1042 | +/// - HTML, code blocks, and everything else are ignored. |
| 1043 | +/// |
| 1044 | +/// Returns a tuple of the rendered HTML string and whether the output was shortened |
| 1045 | +/// due to the provided `length_limit`. |
| 1046 | +fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) { |
| 1047 | + if md.is_empty() { |
| 1048 | + return (String::new(), false); |
| 1049 | + } |
| 1050 | + |
| 1051 | + let mut s = String::with_capacity(md.len() * 3 / 2); |
| 1052 | + let mut text_length = 0; |
| 1053 | + let mut stopped_early = false; |
| 1054 | + |
| 1055 | + fn push(s: &mut String, text_length: &mut usize, text: &str) { |
| 1056 | + s.push_str(text); |
| 1057 | + *text_length += text.len(); |
| 1058 | + }; |
| 1059 | + |
| 1060 | + 'outer: for event in Parser::new_ext(md, Options::ENABLE_STRIKETHROUGH) { |
| 1061 | + match &event { |
| 1062 | + Event::Text(text) => { |
| 1063 | + for word in text.split_inclusive(char::is_whitespace) { |
| 1064 | + if text_length + word.len() >= length_limit { |
| 1065 | + stopped_early = true; |
| 1066 | + break 'outer; |
| 1067 | + } |
| 1068 | + |
| 1069 | + push(&mut s, &mut text_length, word); |
| 1070 | + } |
| 1071 | + } |
| 1072 | + Event::Code(code) => { |
| 1073 | + if text_length + code.len() >= length_limit { |
| 1074 | + stopped_early = true; |
| 1075 | + break; |
| 1076 | + } |
| 1077 | + |
| 1078 | + s.push_str("<code>"); |
| 1079 | + push(&mut s, &mut text_length, code); |
| 1080 | + s.push_str("</code>"); |
| 1081 | + } |
| 1082 | + Event::Start(tag) => match tag { |
| 1083 | + Tag::Emphasis => s.push_str("<em>"), |
| 1084 | + Tag::Strong => s.push_str("<strong>"), |
| 1085 | + Tag::CodeBlock(..) => break, |
| 1086 | + _ => {} |
| 1087 | + }, |
| 1088 | + Event::End(tag) => match tag { |
| 1089 | + Tag::Emphasis => s.push_str("</em>"), |
| 1090 | + Tag::Strong => s.push_str("</strong>"), |
| 1091 | + Tag::Paragraph => break, |
| 1092 | + _ => {} |
| 1093 | + }, |
| 1094 | + Event::HardBreak | Event::SoftBreak => { |
| 1095 | + if text_length + 1 >= length_limit { |
| 1096 | + stopped_early = true; |
| 1097 | + break; |
| 1098 | + } |
| 1099 | + |
| 1100 | + push(&mut s, &mut text_length, " "); |
| 1101 | + } |
| 1102 | + _ => {} |
| 1103 | + } |
| 1104 | + } |
| 1105 | + |
| 1106 | + (s, stopped_early) |
| 1107 | +} |
| 1108 | + |
| 1109 | +/// Renders a shortened first paragraph of the given Markdown as a subset of Markdown, |
| 1110 | +/// making it suitable for contexts like the search index. |
| 1111 | +/// |
| 1112 | +/// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened. |
| 1113 | +/// |
| 1114 | +/// See [`markdown_summary_with_limit`] for details about what is rendered and what is not. |
| 1115 | +crate fn short_markdown_summary(markdown: &str) -> String { |
| 1116 | + let (mut s, was_shortened) = markdown_summary_with_limit(markdown, 59); |
| 1117 | + |
| 1118 | + if was_shortened { |
| 1119 | + s.push('…'); |
| 1120 | + } |
| 1121 | + |
| 1122 | + s |
| 1123 | +} |
| 1124 | + |
1040 | 1125 | /// Renders the first paragraph of the provided markdown as plain text.
|
| 1126 | +/// Useful for alt-text. |
1041 | 1127 | ///
|
1042 | 1128 | /// - Headings, links, and formatting are stripped.
|
1043 | 1129 | /// - Inline code is rendered as-is, surrounded by backticks.
|
|
0 commit comments