Merge pull request #788 from weihanglo/feat/non-ascii-heading-anchor

Allow non alphabetic initial in heading anchor
This commit is contained in:
Michael Bryan 2018-10-23 19:21:44 +08:00 committed by GitHub
commit b0513ee771
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 34 additions and 19 deletions

View File

@ -21,9 +21,10 @@ pub fn collapse_whitespace<'a>(text: &'a str) -> Cow<'a, str> {
RE.replace_all(text, " ") RE.replace_all(text, " ")
} }
/// Convert the given string to a valid HTML element ID /// Convert the given string to a valid HTML element ID.
/// The only restriction is that the ID must not contain any ASCII whitespace.
pub fn normalize_id(content: &str) -> String { pub fn normalize_id(content: &str) -> String {
let mut ret = content content
.chars() .chars()
.filter_map(|ch| { .filter_map(|ch| {
if ch.is_alphanumeric() || ch == '_' || ch == '-' { if ch.is_alphanumeric() || ch == '_' || ch == '-' {
@ -33,16 +34,7 @@ pub fn normalize_id(content: &str) -> String {
} else { } else {
None None
} }
}).collect::<String>(); }).collect::<String>()
// Ensure that the first character is [A-Za-z]
if ret
.chars()
.next()
.map_or(false, |c| !c.is_ascii_alphabetic())
{
ret.insert(0, 'a');
}
ret
} }
/// Generate an ID for use with anchors which is derived from a "normalised" /// Generate an ID for use with anchors which is derived from a "normalised"
@ -328,28 +320,51 @@ more text with spaces
#[test] #[test]
fn it_generates_anchors() { fn it_generates_anchors() {
assert_eq!(
id_from_content("## `--passes`: add more rustdoc passes"),
"a--passes-add-more-rustdoc-passes"
);
assert_eq!( assert_eq!(
id_from_content("## Method-call expressions"), id_from_content("## Method-call expressions"),
"method-call-expressions" "method-call-expressions"
); );
assert_eq!(
id_from_content("## **Bold** title"),
"bold-title"
);
assert_eq!(
id_from_content("## `Code` title"),
"code-title"
);
}
#[test]
fn it_generates_anchors_from_non_ascii_initial() {
assert_eq!(
id_from_content("## `--passes`: add more rustdoc passes"),
"--passes-add-more-rustdoc-passes"
);
assert_eq!(
id_from_content("## 中文標題 CJK title"),
"中文標題-cjk-title"
);
assert_eq!(
id_from_content("## Über"),
"Über"
);
} }
#[test] #[test]
fn it_normalizes_ids() { fn it_normalizes_ids() {
assert_eq!( assert_eq!(
normalize_id("`--passes`: add more rustdoc passes"), normalize_id("`--passes`: add more rustdoc passes"),
"a--passes-add-more-rustdoc-passes" "--passes-add-more-rustdoc-passes"
); );
assert_eq!( assert_eq!(
normalize_id("Method-call 🐙 expressions \u{1f47c}"), normalize_id("Method-call 🐙 expressions \u{1f47c}"),
"method-call--expressions-" "method-call--expressions-"
); );
assert_eq!(normalize_id("_-_12345"), "a_-_12345"); assert_eq!(normalize_id("_-_12345"), "_-_12345");
assert_eq!(normalize_id("12345"), "a12345"); assert_eq!(normalize_id("12345"), "12345");
assert_eq!(normalize_id("中文"), "中文");
assert_eq!(normalize_id("にほんご"), "にほんご");
assert_eq!(normalize_id("한국어"), "한국어");
assert_eq!(normalize_id(""), ""); assert_eq!(normalize_id(""), "");
} }
} }