From d28cf53009ae7e86f3883ae050c43756482f1a5d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 25 Feb 2024 13:42:44 -0800 Subject: [PATCH] Rename curly-quotes to smart-punctuation. --- guide/src/format/configuration/renderers.md | 8 +-- guide/src/format/markdown.md | 4 +- src/book/mod.rs | 30 +++++++----- src/config.rs | 51 ++++++++++++++++++-- src/renderer/html_handlebars/hbs_renderer.rs | 12 +++-- src/utils/mod.rs | 16 +++--- 6 files changed, 89 insertions(+), 32 deletions(-) diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index 7e743014..3ff6b3a0 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -97,7 +97,7 @@ description = "The example book covers examples." theme = "my-theme" default-theme = "light" preferred-dark-theme = "navy" -curly-quotes = true +smart-punctuation = true mathjax-support = false copy-fonts = true additional-css = ["custom.css", "custom2.css"] @@ -122,8 +122,10 @@ The following configuration options are available: the browser requests the dark version of the site via the ['prefers-color-scheme'](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) CSS media query. Defaults to `navy`. -- **curly-quotes:** Convert straight quotes to curly quotes, except for those - that occur in code blocks and code spans. Defaults to `false`. +- **smart-punctuation:** Converts quotes to curly quotes, `...` to `…`, `--` to en-dash, and `---` to em-dash. + See [Smart Punctuation]. + Defaults to `false`. +- **curly-quotes:** Deprecated alias for `smart-punctuation`. - **mathjax-support:** Adds support for [MathJax](../mathjax.md). Defaults to `false`. - **copy-fonts:** (**Deprecated**) If `true` (the default), mdBook uses its built-in fonts which are copied to the output directory. diff --git a/guide/src/format/markdown.md b/guide/src/format/markdown.md index 7c9b22bb..f837d54c 100644 --- a/guide/src/format/markdown.md +++ b/guide/src/format/markdown.md @@ -214,12 +214,12 @@ characters: So, no need to manually enter those Unicode characters! This feature is disabled by default. -To enable it, see the [`output.html.curly-quotes`] config option. +To enable it, see the [`output.html.smart-punctuation`] config option. [strikethrough]: https://github.github.com/gfm/#strikethrough-extension- [tables]: https://github.github.com/gfm/#tables-extension- [task list extension]: https://github.github.com/gfm/#task-list-items-extension- -[`output.html.curly-quotes`]: configuration/renderers.md#html-renderer-options +[`output.html.smart-punctuation`]: configuration/renderers.md#html-renderer-options ### Heading attributes diff --git a/src/book/mod.rs b/src/book/mod.rs index 166f6511..c0ab8a54 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -70,18 +70,24 @@ impl MDBook { config.update_from_env(); - if config - .html_config() - .map_or(false, |html| html.google_analytics.is_some()) - { - warn!( - "The output.html.google-analytics field has been deprecated; \ - it will be removed in a future release.\n\ - Consider placing the appropriate site tag code into the \ - theme/head.hbs file instead.\n\ - The tracking code may be found in the Google Analytics Admin page.\n\ - " - ); + if let Some(html_config) = config.html_config() { + if html_config.google_analytics.is_some() { + warn!( + "The output.html.google-analytics field has been deprecated; \ + it will be removed in a future release.\n\ + Consider placing the appropriate site tag code into the \ + theme/head.hbs file instead.\n\ + The tracking code may be found in the Google Analytics Admin page.\n\ + " + ); + } + if html_config.curly_quotes { + warn!( + "The output.html.curly-quotes field has been renamed to \ + output.html.smart-punctuation.\n\ + Use the new name in book.toml to remove this warning." + ); + } } if log_enabled!(log::Level::Trace) { diff --git a/src/config.rs b/src/config.rs index 67b1a700..4840c030 100644 --- a/src/config.rs +++ b/src/config.rs @@ -526,7 +526,9 @@ pub struct HtmlConfig { /// The theme to use if the browser requests the dark version of the site. /// Defaults to 'navy'. pub preferred_dark_theme: Option, - /// Use "smart quotes" instead of the usual `"` character. + /// Supports smart quotes, apostrophes, ellipsis, en-dash, and em-dash. + pub smart_punctuation: bool, + /// Deprecated alias for `smart_punctuation`. pub curly_quotes: bool, /// Should mathjax be enabled? pub mathjax_support: bool, @@ -590,6 +592,7 @@ impl Default for HtmlConfig { theme: None, default_theme: None, preferred_dark_theme: None, + smart_punctuation: false, curly_quotes: false, mathjax_support: false, copy_fonts: true, @@ -623,6 +626,11 @@ impl HtmlConfig { None => root.join("theme"), } } + + /// Returns `true` if smart punctuation is enabled. + pub fn smart_punctuation(&self) -> bool { + self.smart_punctuation || self.curly_quotes + } } /// Configuration for how to render the print icon, print.html, and print.css. @@ -798,7 +806,7 @@ mod tests { [output.html] theme = "./themedir" default-theme = "rust" - curly-quotes = true + smart-punctuation = true google-analytics = "123456" additional-css = ["./foo/bar/baz.css"] git-repository-url = "https://foo.com/" @@ -845,7 +853,7 @@ mod tests { runnable: true, }; let html_should_be = HtmlConfig { - curly_quotes: true, + smart_punctuation: true, google_analytics: Some(String::from("123456")), additional_css: vec![PathBuf::from("./foo/bar/baz.css")], theme: Some(PathBuf::from("./themedir")), @@ -1025,7 +1033,7 @@ mod tests { [output.html] destination = "my-book" # the output files will be generated in `root/my-book` instead of `root/book` theme = "my-theme" - curly-quotes = true + smart-punctuation = true google-analytics = "123456" additional-css = ["custom.css", "custom2.css"] additional-js = ["custom.js"] @@ -1050,7 +1058,7 @@ mod tests { let html_should_be = HtmlConfig { theme: Some(PathBuf::from("my-theme")), - curly_quotes: true, + smart_punctuation: true, google_analytics: Some(String::from("123456")), additional_css: vec![PathBuf::from("custom.css"), PathBuf::from("custom2.css")], additional_js: vec![PathBuf::from("custom.js")], @@ -1320,4 +1328,37 @@ mod tests { assert!(html_config.print.enable); assert!(!html_config.print.page_break); } + + #[test] + fn curly_quotes_or_smart_punctuation() { + let src = r#" + [book] + title = "mdBook Documentation" + + [output.html] + smart-punctuation = true + "#; + let config = Config::from_str(src).unwrap(); + assert_eq!(config.html_config().unwrap().smart_punctuation(), true); + + let src = r#" + [book] + title = "mdBook Documentation" + + [output.html] + curly-quotes = true + "#; + let config = Config::from_str(src).unwrap(); + assert_eq!(config.html_config().unwrap().smart_punctuation(), true); + + let src = r#" + [book] + title = "mdBook Documentation" + "#; + let config = Config::from_str(src).unwrap(); + assert_eq!( + config.html_config().unwrap_or_default().smart_punctuation(), + false + ); + } } diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index b706108e..30d4c84b 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -54,10 +54,13 @@ impl HtmlHandlebars { .insert("git_repository_edit_url".to_owned(), json!(edit_url)); } - let content = utils::render_markdown(&ch.content, ctx.html_config.curly_quotes); + let content = utils::render_markdown(&ch.content, ctx.html_config.smart_punctuation()); - let fixed_content = - utils::render_markdown_with_path(&ch.content, ctx.html_config.curly_quotes, Some(path)); + let fixed_content = utils::render_markdown_with_path( + &ch.content, + ctx.html_config.smart_punctuation(), + Some(path), + ); if !ctx.is_index && ctx.html_config.print.page_break { // Add page break between chapters // See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before @@ -164,7 +167,8 @@ impl HtmlHandlebars { .to_string() } }; - let html_content_404 = utils::render_markdown(&content_404, html_config.curly_quotes); + let html_content_404 = + utils::render_markdown(&content_404, html_config.smart_punctuation()); let mut data_404 = data.clone(); let base_url = if let Some(site_url) = &html_config.site_url { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index c0be2030..2b17cc7d 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -190,26 +190,30 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> { } /// Wrapper around the pulldown-cmark parser for rendering markdown to HTML. -pub fn render_markdown(text: &str, curly_quotes: bool) -> String { - render_markdown_with_path(text, curly_quotes, None) +pub fn render_markdown(text: &str, smart_punctuation: bool) -> String { + render_markdown_with_path(text, smart_punctuation, None) } -pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_> { +pub fn new_cmark_parser(text: &str, smart_punctuation: bool) -> Parser<'_> { let mut opts = Options::empty(); opts.insert(Options::ENABLE_TABLES); opts.insert(Options::ENABLE_FOOTNOTES); opts.insert(Options::ENABLE_STRIKETHROUGH); opts.insert(Options::ENABLE_TASKLISTS); opts.insert(Options::ENABLE_HEADING_ATTRIBUTES); - if curly_quotes { + if smart_punctuation { opts.insert(Options::ENABLE_SMART_PUNCTUATION); } Parser::new_ext(text, opts) } -pub fn render_markdown_with_path(text: &str, curly_quotes: bool, path: Option<&Path>) -> String { +pub fn render_markdown_with_path( + text: &str, + smart_punctuation: bool, + path: Option<&Path>, +) -> String { let mut s = String::with_capacity(text.len() * 3 / 2); - let p = new_cmark_parser(text, curly_quotes); + let p = new_cmark_parser(text, smart_punctuation); let events = p .map(clean_codeblock_headers) .map(|event| adjust_links(event, path))