Skip to content

Commit

Permalink
Apply patch by ehuss
Browse files Browse the repository at this point in the history
Signed-off-by: Hollow Man <[email protected]>
  • Loading branch information
HollowMan6 committed Jun 11, 2023
1 parent ae8a216 commit 2ce21d2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 33 deletions.
5 changes: 5 additions & 0 deletions guide/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ heading-split-level = 2

[output.html.redirect]
"/format/config.html" = "configuration/index.html"

[output.pdf]

[output.pdf-outline]
like-wkhtmltopdf = true
48 changes: 34 additions & 14 deletions src/renderer/html_handlebars/hbs_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl HtmlHandlebars {
let content = ch.content.clone();
let content = utils::render_markdown(&content, ctx.html_config.curly_quotes);

let fixed_content = utils::render_markdown_with_path_and_redirects(
let printed_item = utils::render_markdown_with_path_and_redirects(
&ch.content,
ctx.html_config.curly_quotes,
Some(path),
Expand All @@ -70,7 +70,7 @@ impl HtmlHandlebars {
print_content
.push_str(r#"<div style="break-before: page; page-break-before: always;"></div>"#);
}
let path_id = {
let print_page_id = {
let mut base = path.display().to_string();
if base.ends_with(".md") {
base.truncate(base.len() - 3);
Expand All @@ -84,10 +84,10 @@ impl HtmlHandlebars {
// We have to build header links in advance so that we can know the ranges
// for the headers in one page.
// Insert a dummy div to make sure that we can locate the specific page.
print_content.push_str(&(format!(r#"<div id="{}"></div>"#, &path_id)));
print_content.push_str(&(format!(r#"<div id="{print_page_id}"></div>"#)));
print_content.push_str(&build_header_links(
&build_print_element_id(&fixed_content, &path_id),
Some(path_id),
&build_print_element_id(&printed_item, &print_page_id),
Some(print_page_id),
));

// Update the context with data for this file
Expand Down Expand Up @@ -234,6 +234,22 @@ impl HtmlHandlebars {
edition: Option<RustEdition>,
) -> String {
let rendered = build_header_links(&rendered, None);
let rendered = self.post_process_common(rendered, &playground_config, code_config, edition);

rendered
}

/// Applies some post-processing to the HTML to apply some adjustments.
///
/// This common function is used for both normal chapters (via
/// `post_process`) and the combined print page.
fn post_process_common(
&self,
rendered: String,
playground_config: &Playground,
code_config: &Code,
edition: Option<RustEdition>,
) -> String {
let rendered = fix_code_blocks(&rendered);
let rendered = add_playground_pre(&rendered, playground_config, edition);
let rendered = hide_lines(&rendered, code_config);
Expand Down Expand Up @@ -620,7 +636,7 @@ impl Renderer for HtmlHandlebars {
debug!("Render template");
let rendered = handlebars.render("index", &data)?;

let rendered = self.post_process(
let rendered = self.post_process_common(
rendered,
&html_config.playground,
&html_config.code,
Expand Down Expand Up @@ -829,7 +845,7 @@ fn make_data(

/// Go through the rendered print page HTML,
/// add path id prefix to all the elements id as well as footnote links.
fn build_print_element_id(html: &str, path_id: &str) -> String {
fn build_print_element_id(html: &str, print_page_id: &str) -> String {
static ALL_ID: Lazy<Regex> = Lazy::new(|| Regex::new(r#"(<[^>]*?id=")([^"]+?)""#).unwrap());
static FOOTNOTE_ID: Lazy<Regex> = Lazy::new(|| {
Regex::new(
Expand All @@ -839,19 +855,22 @@ fn build_print_element_id(html: &str, path_id: &str) -> String {
});

let temp_html = ALL_ID.replace_all(html, |caps: &Captures<'_>| {
format!("{}{}-{}\"", &caps[1], path_id, &caps[2])
format!("{}{}-{}\"", &caps[1], print_page_id, &caps[2])
});

FOOTNOTE_ID
.replace_all(&temp_html, |caps: &Captures<'_>| {
format!("{}{}-{}\"", &caps[1], path_id, &caps[2])
format!("{}{}-{}\"", &caps[1], print_page_id, &caps[2])
})
.into_owned()
}

/// Goes through the rendered HTML, making sure all header tags have
/// an anchor respectively so people can link to sections directly.
fn build_header_links(html: &str, path_id: Option<&str>) -> String {
///
/// `print_page_id` should be set to the print page ID prefix when adjusting the
/// print page.
fn build_header_links(html: &str, print_page_id: Option<&str>) -> String {
static BUILD_HEADER_LINKS: Lazy<Regex> = Lazy::new(|| {
Regex::new(r#"<h(\d)(?: id="([^"]+)")?(?: class="([^"]+)")?>(.*?)</h\d>"#).unwrap()
});
Expand Down Expand Up @@ -880,7 +899,7 @@ fn build_header_links(html: &str, path_id: Option<&str>) -> String {
caps.get(2).map(|x| x.as_str().to_string()),
caps.get(3).map(|x| x.as_str().to_string()),
&mut id_counter,
path_id,
print_page_id,
)
})
.into_owned()
Expand All @@ -896,10 +915,11 @@ fn insert_link_into_header(
id: Option<String>,
classes: Option<String>,
id_counter: &mut HashMap<String, usize>,
path_id: Option<&str>,
print_page_id: Option<&str>,
) -> String {
let id = if let Some(path_id) = path_id {
id.unwrap_or_else(|| utils::unique_id_from_content_with_path(content, id_counter, path_id))
let id = if let Some(print_page_id) = print_page_id {
let with_prefix = format!("{} {}", print_page_id, content);
id.unwrap_or_else(|| utils::unique_id_from_content(&with_prefix, id_counter))
} else {
id.unwrap_or_else(|| utils::unique_id_from_content(content, id_counter))
};
Expand Down
34 changes: 15 additions & 19 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,6 @@ pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap<String, us
unique_id
}

pub(crate) fn unique_id_from_content_with_path(
content: &str,
id_counter: &mut HashMap<String, usize>,
path_id: &str,
) -> String {
unique_id_from_content(&format!("{} {}", path_id, content), id_counter)
}

/// Improve the path to try remove and solve .. token,
/// This assumes that `a/b/../c` is `a/c`.
///
Expand Down Expand Up @@ -120,7 +112,7 @@ fn normalize_path<P: AsRef<Path>>(path: P) -> String {
}

/// Converts a relative URL path to a reference ID for the print page.
fn normalize_path_id(mut path: String) -> String {
fn normalize_print_page_id(mut path: String) -> String {
path = path
.replace("/", "-")
.replace(".html#", "-")
Expand All @@ -136,13 +128,8 @@ fn normalize_path_id(mut path: String) -> String {
///
/// This adjusts links, such as turning `.md` extensions to `.html`.
///
/// `path` is the path to the page being rendered relative to the root of the
/// book. This is used for the `print.html` page so that links on the print
/// page go to the anchors that has a path id prefix. Normal page rendering
/// sets `path` to None.
///
/// `redirects` is also only for the print page. It's for adjusting links to
/// a redirected location to go to the correct spot on the `print.html` page.
/// See [`render_markdown_with_path_and_redirects`] for a description of
/// `path` and `redirects`.
fn adjust_links<'a>(
event: Event<'a>,
path: Option<&Path>,
Expand Down Expand Up @@ -231,7 +218,7 @@ fn adjust_links<'a>(

let mut fixed_anchor_for_print = String::new();
fixed_anchor_for_print.push_str("#");
fixed_anchor_for_print.push_str(&normalize_path_id(normalized_path));
fixed_anchor_for_print.push_str(&normalize_print_page_id(normalized_path));
CowStr::from(fixed_anchor_for_print)
}

Expand Down Expand Up @@ -266,7 +253,7 @@ fn adjust_links<'a>(
}
format!(
"#{}{}",
normalize_path_id(normalize_path(base)),
normalize_print_page_id(normalize_path(base)),
dest.replace("#", "-")
)
.into()
Expand Down Expand Up @@ -378,7 +365,16 @@ pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> {
Parser::new_ext(text, opts)
}

pub fn render_markdown_with_path_and_redirects(
/// Renders markdown to HTML.
///
/// `path` is the path to the page being rendered relative to the root of the
/// book. This is used for the `print.html` page so that links on the print
/// page go to the anchors that has a path id prefix. Normal page rendering
/// sets `path` to None.
///
/// `redirects` is also only for the print page. It's for adjusting links to
/// a redirected location to go to the correct spot on the `print.html` page.
pub(crate) fn render_markdown_with_path_and_redirects(
text: &str,
curly_quotes: bool,
path: Option<&Path>,
Expand Down

0 comments on commit 2ce21d2

Please sign in to comment.