From 972c61fa76d0bd972538a762cd62afca4c917a33 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 18 Feb 2022 15:27:24 +0000 Subject: [PATCH] search: fix anchor ids for duplicate headers --- src/renderer/html_handlebars/hbs_renderer.rs | 11 +- src/renderer/html_handlebars/search.rs | 3 +- src/utils/mod.rs | 57 +- tests/dummy_book/src/SUMMARY.md | 1 + .../dummy_book/src/first/duplicate-headers.md | 9 + tests/rendered_output.rs | 10 +- tests/searchindex_fixture.json | 600 ++++++++++++++---- 7 files changed, 554 insertions(+), 137 deletions(-) create mode 100644 tests/dummy_book/src/first/duplicate-headers.md diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 69dc3124..c4c2862d 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -768,16 +768,7 @@ fn insert_link_into_header( content: &str, id_counter: &mut HashMap, ) -> String { - let raw_id = utils::id_from_content(content); - - let id_count = id_counter.entry(raw_id.clone()).or_insert(0); - - let id = match *id_count { - 0 => raw_id, - other => format!("{}-{}", raw_id, other), - }; - - *id_count += 1; + let id = utils::unique_id_from_content(content, id_counter); format!( r##"{text}"##, diff --git a/src/renderer/html_handlebars/search.rs b/src/renderer/html_handlebars/search.rs index 39b59800..5dd063da 100644 --- a/src/renderer/html_handlebars/search.rs +++ b/src/renderer/html_handlebars/search.rs @@ -97,6 +97,7 @@ fn render_item( breadcrumbs.push(chapter.name.clone()); + let mut id_counter = HashMap::new(); while let Some(event) = p.next() { match event { Event::Start(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { @@ -120,7 +121,7 @@ fn render_item( } Event::End(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { in_heading = false; - section_id = Some(utils::id_from_content(&heading)); + section_id = Some(utils::unique_id_from_content(&heading, &mut id_counter)); breadcrumbs.push(heading.clone()); } Event::Start(Tag::FootnoteDefinition(name)) => { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 44494a8b..cf213264 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -9,6 +9,7 @@ use regex::Regex; use pulldown_cmark::{html, CodeBlockKind, CowStr, Event, Options, Parser, Tag}; use std::borrow::Cow; +use std::collections::HashMap; use std::fmt::Write; use std::path::Path; @@ -44,6 +45,8 @@ pub fn normalize_id(content: &str) -> String { /// Generate an ID for use with anchors which is derived from a "normalised" /// string. +// This function should be made private when the deprecation expires. +#[deprecated(since = "0.4.16", note = "use unique_id_from_content instead")] pub fn id_from_content(content: &str) -> String { let mut content = content.to_string(); @@ -59,10 +62,30 @@ pub fn id_from_content(content: &str) -> String { // Remove spaces and hashes indicating a header let trimmed = content.trim().trim_start_matches('#').trim(); - normalize_id(trimmed) } +/// Generate an ID for use with anchors which is derived from a "normalised" +/// string. +/// +/// Each ID returned will be unique, if the same `id_counter` is provided on +/// each call. +pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap) -> String { + let id = { + #[allow(deprecated)] + id_from_content(content) + }; + + // If we have headers with the same normalized id, append an incrementing counter + let id_count = id_counter.entry(id.clone()).or_insert(0); + let unique_id = match *id_count { + 0 => id, + id_count => format!("{}-{}", id, id_count), + }; + *id_count += 1; + unique_id +} + /// Fix links to the correct location. /// /// This adjusts links, such as turning `.md` extensions to `.html`. @@ -332,8 +355,9 @@ more text with spaces } } - mod html_munging { - use super::super::{id_from_content, normalize_id}; + #[allow(deprecated)] + mod id_from_content { + use super::super::id_from_content; #[test] fn it_generates_anchors() { @@ -361,6 +385,10 @@ more text with spaces ); assert_eq!(id_from_content("## Über"), "Über"); } + } + + mod html_munging { + use super::super::{normalize_id, unique_id_from_content}; #[test] fn it_normalizes_ids() { @@ -379,5 +407,28 @@ more text with spaces assert_eq!(normalize_id("한국어"), "한국어"); assert_eq!(normalize_id(""), ""); } + + #[test] + fn it_generates_unique_ids_from_content() { + // Same id if not given shared state + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut Default::default()), + "中文標題-cjk-title" + ); + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut Default::default()), + "中文標題-cjk-title" + ); + + // Different id if given shared state + let mut id_counter = Default::default(); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über"); + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut id_counter), + "中文標題-cjk-title" + ); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über-1"); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über-2"); + } } } diff --git a/tests/dummy_book/src/SUMMARY.md b/tests/dummy_book/src/SUMMARY.md index e12e1254..49b64a54 100644 --- a/tests/dummy_book/src/SUMMARY.md +++ b/tests/dummy_book/src/SUMMARY.md @@ -13,6 +13,7 @@ - [Markdown](first/markdown.md) - [Unicode](first/unicode.md) - [No Headers](first/no-headers.md) + - [Duplicate Headers](first/duplicate-headers.md) - [Second Chapter](second.md) - [Nested Chapter](second/nested.md) diff --git a/tests/dummy_book/src/first/duplicate-headers.md b/tests/dummy_book/src/first/duplicate-headers.md new file mode 100644 index 00000000..83522b44 --- /dev/null +++ b/tests/dummy_book/src/first/duplicate-headers.md @@ -0,0 +1,9 @@ +# Duplicate headers + +This page validates behaviour of duplicate headers. + +# Header Text + +# Header Text + +# header-text diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 5ec6e64b..f3d11d53 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -35,6 +35,7 @@ const TOC_SECOND_LEVEL: &[&str] = &[ "1.4. Markdown", "1.5. Unicode", "1.6. No Headers", + "1.7. Duplicate Headers", "2.1. Nested Chapter", ]; @@ -633,11 +634,12 @@ mod search { let some_section = get_doc_ref("first/index.html#some-section"); let summary = get_doc_ref("first/includes.html#summary"); let no_headers = get_doc_ref("first/no-headers.html"); + let duplicate_headers_1 = get_doc_ref("first/duplicate-headers.html#header-text-1"); let conclusion = get_doc_ref("conclusion.html#conclusion"); let bodyidx = &index["index"]["index"]["body"]["root"]; let textidx = &bodyidx["t"]["e"]["x"]["t"]; - assert_eq!(textidx["df"], 2); + assert_eq!(textidx["df"], 5); assert_eq!(textidx["docs"][&first_chapter]["tf"], 1.0); assert_eq!(textidx["docs"][&introduction]["tf"], 1.0); @@ -646,7 +648,7 @@ mod search { assert_eq!(docs[&some_section]["body"], ""); assert_eq!( docs[&summary]["body"], - "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Second Chapter Nested Chapter Conclusion" + "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Duplicate Headers Second Chapter Nested Chapter Conclusion" ); assert_eq!( docs[&summary]["breadcrumbs"], @@ -657,6 +659,10 @@ mod search { docs[&no_headers]["breadcrumbs"], "First Chapter » No Headers" ); + assert_eq!( + docs[&duplicate_headers_1]["breadcrumbs"], + "First Chapter » Duplicate Headers » Header Text" + ); assert_eq!( docs[&no_headers]["body"], "Capybara capybara capybara. Capybara capybara capybara." diff --git a/tests/searchindex_fixture.json b/tests/searchindex_fixture.json index 32c44a1b..9c349b6b 100644 --- a/tests/searchindex_fixture.json +++ b/tests/searchindex_fixture.json @@ -19,6 +19,10 @@ "first/markdown.html#tasklisks", "first/unicode.html#unicode-stress-tests", "first/no-headers.html", + "first/duplicate-headers.html#duplicate-headers", + "first/duplicate-headers.html#header-text", + "first/duplicate-headers.html#header-text-1", + "first/duplicate-headers.html#header-text-2", "second.html#second-chapter", "second/nested.html#testing-relative-links-for-the-print-page", "second/nested.html#some-section", @@ -38,7 +42,7 @@ "title": 1 }, "10": { - "body": 17, + "body": 19, "breadcrumbs": 4, "title": 1 }, @@ -83,8 +87,8 @@ "title": 2 }, "19": { - "body": 20, - "breadcrumbs": 4, + "body": 5, + "breadcrumbs": 6, "title": 2 }, "2": { @@ -93,16 +97,36 @@ "title": 2 }, "20": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "21": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "22": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "23": { + "body": 20, + "breadcrumbs": 4, + "title": 2 + }, + "24": { "body": 18, "breadcrumbs": 9, "title": 5 }, - "21": { + "25": { "body": 0, "breadcrumbs": 5, "title": 1 }, - "22": { + "26": { "body": 3, "breadcrumbs": 2, "title": 1 @@ -157,7 +181,7 @@ "title": "Introduction" }, "10": { - "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Second Chapter Nested Chapter Conclusion", + "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Duplicate Headers Second Chapter Nested Chapter Conclusion", "breadcrumbs": "First Chapter » Includes » Summary", "id": "10", "title": "Summary" @@ -211,10 +235,10 @@ "title": "First Chapter" }, "19": { - "body": "This makes sure you can insert runnable Rust files. fn main() { println!(\"Hello World!\");\n#\n# // You can even hide lines! :D\n# println!(\"I am hidden! Expand the code snippet to see me\");\n}", - "breadcrumbs": "Second Chapter » Second Chapter", + "body": "This page validates behaviour of duplicate headers.", + "breadcrumbs": "First Chapter » Duplicate Headers » Duplicate headers", "id": "19", - "title": "Second Chapter" + "title": "Duplicate headers" }, "2": { "body": "more text.", @@ -223,21 +247,45 @@ "title": "First Chapter" }, "20": { - "body": "When we link to the first section , it should work on both the print page and the non-print page. A fragment link should work. Link outside . Some image HTML Link", - "breadcrumbs": "Second Chapter » Nested Chapter » Testing relative links for the print page", + "body": "", + "breadcrumbs": "First Chapter » Duplicate Headers » Header Text", "id": "20", - "title": "Testing relative links for the print page" + "title": "Header Text" }, "21": { "body": "", - "breadcrumbs": "Second Chapter » Nested Chapter » Some section", + "breadcrumbs": "First Chapter » Duplicate Headers » Header Text", "id": "21", - "title": "Some section" + "title": "Header Text" }, "22": { + "body": "", + "breadcrumbs": "First Chapter » Duplicate Headers » header-text", + "id": "22", + "title": "header-text" + }, + "23": { + "body": "This makes sure you can insert runnable Rust files. fn main() { println!(\"Hello World!\");\n#\n# // You can even hide lines! :D\n# println!(\"I am hidden! Expand the code snippet to see me\");\n}", + "breadcrumbs": "Second Chapter » Second Chapter", + "id": "23", + "title": "Second Chapter" + }, + "24": { + "body": "When we link to the first section , it should work on both the print page and the non-print page. A fragment link should work. Link outside . Some image HTML Link", + "breadcrumbs": "Second Chapter » Nested Chapter » Testing relative links for the print page", + "id": "24", + "title": "Testing relative links for the print page" + }, + "25": { + "body": "", + "breadcrumbs": "Second Chapter » Nested Chapter » Some section", + "id": "25", + "title": "Some section" + }, + "26": { "body": "I put <HTML> in here!", "breadcrumbs": "Conclusion » Conclusion", - "id": "22", + "id": "26", "title": "Conclusion" }, "3": { @@ -283,7 +331,7 @@ "title": "Includes" } }, - "length": 23, + "length": 27, "save": true }, "fields": [ @@ -478,6 +526,38 @@ "e": { "df": 0, "docs": {}, + "h": { + "a": { + "df": 0, + "docs": {}, + "v": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "o": { + "df": 0, + "docs": {}, + "u": { + "df": 0, + "docs": {}, + "r": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + } + } + } + } + } + }, + "df": 0, + "docs": {} + }, "t": { "df": 0, "docs": {}, @@ -539,7 +619,7 @@ "h": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -738,10 +818,10 @@ "18": { "tf": 1.0 }, - "19": { + "2": { "tf": 1.0 }, - "2": { + "23": { "tf": 1.0 }, "4": { @@ -783,7 +863,7 @@ "e": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "4": { @@ -850,7 +930,7 @@ "10": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -922,7 +1002,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } }, @@ -947,6 +1027,29 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 2, + "docs": { + "10": { + "tf": 1.0 + }, + "19": { + "tf": 1.4142135623730951 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -1012,7 +1115,7 @@ "n": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1053,7 +1156,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1122,7 +1225,7 @@ "0": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 }, "4": { @@ -1158,7 +1261,7 @@ "2": { "tf": 1.0 }, - "20": { + "24": { "tf": 1.0 } } @@ -1169,7 +1272,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1243,7 +1346,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1289,9 +1392,21 @@ "df": 0, "docs": {}, "r": { - "df": 1, + "df": 5, "docs": { "10": { + "tf": 1.4142135623730951 + }, + "19": { + "tf": 1.4142135623730951 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { "tf": 1.0 } } @@ -1336,7 +1451,7 @@ "0": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -1354,7 +1469,7 @@ "n": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1369,7 +1484,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1387,7 +1502,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1405,7 +1520,7 @@ "g": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1477,7 +1592,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1613,7 +1728,7 @@ "14": { "tf": 1.4142135623730951 }, - "19": { + "23": { "tf": 1.0 }, "6": { @@ -1624,7 +1739,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.23606797749979 } } @@ -1678,7 +1793,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -1706,7 +1821,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1724,7 +1839,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1853,7 +1968,7 @@ "n": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1892,7 +2007,7 @@ "d": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1912,9 +2027,12 @@ "df": 0, "docs": {}, "e": { - "df": 1, + "df": 2, "docs": { - "20": { + "19": { + "tf": 1.0 + }, + "24": { "tf": 1.7320508075688772 } } @@ -2027,7 +2145,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.7320508075688772 } }, @@ -2055,7 +2173,7 @@ "o": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2067,7 +2185,7 @@ "i": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2093,7 +2211,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -2129,7 +2247,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -2241,7 +2359,7 @@ "l": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2279,7 +2397,7 @@ }, "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2304,7 +2422,7 @@ "10": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 } } @@ -2325,10 +2443,10 @@ "n": { "df": 4, "docs": { - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 }, "3": { @@ -2348,7 +2466,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2372,7 +2490,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2663,7 +2781,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2749,7 +2867,7 @@ "17": { "tf": 1.0 }, - "20": { + "24": { "tf": 1.0 }, "6": { @@ -2762,13 +2880,22 @@ "df": 0, "docs": {}, "t": { - "df": 2, + "df": 5, "docs": { "1": { "tf": 1.0 }, "2": { "tf": 1.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 } } } @@ -2866,6 +2993,30 @@ } } }, + "v": { + "a": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "d": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } + }, + "df": 0, + "docs": {} + }, "w": { "a": { "df": 0, @@ -2898,7 +3049,7 @@ "k": { "df": 2, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 }, "8": { @@ -2913,7 +3064,7 @@ "11": { "tf": 4.69041575982343 }, - "19": { + "23": { "tf": 1.0 } } @@ -3136,6 +3287,38 @@ "e": { "df": 0, "docs": {}, + "h": { + "a": { + "df": 0, + "docs": {}, + "v": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "o": { + "df": 0, + "docs": {}, + "u": { + "df": 0, + "docs": {}, + "r": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + } + } + } + } + } + }, + "df": 0, + "docs": {} + }, "t": { "df": 0, "docs": {}, @@ -3197,7 +3380,7 @@ "h": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -3385,7 +3568,7 @@ "df": 0, "docs": {}, "r": { - "df": 20, + "df": 24, "docs": { "10": { "tf": 2.23606797749979 @@ -3415,15 +3598,27 @@ "tf": 1.4142135623730951 }, "19": { - "tf": 1.7320508075688772 + "tf": 1.0 }, "2": { "tf": 1.7320508075688772 }, "20": { - "tf": 1.4142135623730951 + "tf": 1.0 }, "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + }, + "23": { + "tf": 1.7320508075688772 + }, + "24": { + "tf": 1.4142135623730951 + }, + "25": { "tf": 1.4142135623730951 }, "3": { @@ -3483,7 +3678,7 @@ "e": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "4": { @@ -3550,7 +3745,7 @@ "10": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.7320508075688772 } } @@ -3622,7 +3817,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } }, @@ -3647,6 +3842,38 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 5, + "docs": { + "10": { + "tf": 1.0 + }, + "19": { + "tf": 2.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -3712,7 +3939,7 @@ "n": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -3753,7 +3980,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -3822,7 +4049,7 @@ "0": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 }, "4": { @@ -3844,7 +4071,7 @@ "df": 0, "docs": {}, "t": { - "df": 18, + "df": 22, "docs": { "10": { "tf": 1.4142135623730951 @@ -3873,12 +4100,24 @@ "18": { "tf": 1.4142135623730951 }, + "19": { + "tf": 1.0 + }, "2": { "tf": 1.7320508075688772 }, "20": { "tf": 1.0 }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + }, + "24": { + "tf": 1.0 + }, "3": { "tf": 1.0 }, @@ -3908,7 +4147,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -3982,7 +4221,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4028,13 +4267,25 @@ "df": 0, "docs": {}, "r": { - "df": 2, + "df": 6, "docs": { "10": { - "tf": 1.0 + "tf": 1.4142135623730951 }, "18": { "tf": 1.0 + }, + "19": { + "tf": 2.0 + }, + "20": { + "tf": 1.7320508075688772 + }, + "21": { + "tf": 1.7320508075688772 + }, + "22": { + "tf": 1.7320508075688772 } } } @@ -4078,7 +4329,7 @@ "0": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -4096,7 +4347,7 @@ "n": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -4111,7 +4362,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4129,7 +4380,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4147,7 +4398,7 @@ "g": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4219,7 +4470,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4355,7 +4606,7 @@ "14": { "tf": 1.4142135623730951 }, - "19": { + "23": { "tf": 1.0 }, "6": { @@ -4366,7 +4617,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.449489742783178 } } @@ -4420,7 +4671,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -4448,7 +4699,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -4466,7 +4717,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4582,10 +4833,10 @@ "10": { "tf": 1.4142135623730951 }, - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 }, "4": { @@ -4625,7 +4876,7 @@ "n": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4664,7 +4915,7 @@ "d": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4684,9 +4935,12 @@ "df": 0, "docs": {}, "e": { - "df": 1, + "df": 2, "docs": { - "20": { + "19": { + "tf": 1.0 + }, + "24": { "tf": 2.0 } } @@ -4799,7 +5053,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.0 } }, @@ -4827,7 +5081,7 @@ "o": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4839,7 +5093,7 @@ "i": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4865,7 +5119,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -4904,7 +5158,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 } } @@ -5016,7 +5270,7 @@ "l": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5054,7 +5308,7 @@ }, "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5079,13 +5333,13 @@ "10": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.7320508075688772 }, - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 } } @@ -5106,10 +5360,10 @@ "n": { "df": 4, "docs": { - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.4142135623730951 }, "3": { @@ -5129,7 +5383,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5153,7 +5407,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5444,7 +5698,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5530,7 +5784,7 @@ "17": { "tf": 1.4142135623730951 }, - "20": { + "24": { "tf": 1.4142135623730951 }, "6": { @@ -5543,13 +5797,22 @@ "df": 0, "docs": {}, "t": { - "df": 2, + "df": 5, "docs": { "1": { "tf": 1.0 }, "2": { "tf": 1.0 + }, + "20": { + "tf": 1.4142135623730951 + }, + "21": { + "tf": 1.4142135623730951 + }, + "22": { + "tf": 1.4142135623730951 } } } @@ -5647,6 +5910,30 @@ } } }, + "v": { + "a": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "d": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } + }, + "df": 0, + "docs": {} + }, "w": { "a": { "df": 0, @@ -5679,7 +5966,7 @@ "k": { "df": 2, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 }, "8": { @@ -5694,7 +5981,7 @@ "11": { "tf": 4.69041575982343 }, - "19": { + "23": { "tf": 1.0 } } @@ -5849,10 +6136,10 @@ "18": { "tf": 1.0 }, - "19": { + "2": { "tf": 1.0 }, - "2": { + "23": { "tf": 1.0 }, "4": { @@ -5907,7 +6194,7 @@ "s": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -5941,6 +6228,26 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -6022,6 +6329,39 @@ "h": { "df": 0, "docs": {}, + "e": { + "a": { + "d": { + "df": 0, + "docs": {}, + "e": { + "df": 0, + "docs": {}, + "r": { + "df": 4, + "docs": { + "19": { + "tf": 1.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + } + } + } + } + }, + "df": 0, + "docs": {} + }, + "df": 0, + "docs": {} + }, "i": { "d": { "d": { @@ -6128,7 +6468,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6202,7 +6542,7 @@ "e": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6235,7 +6575,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6253,7 +6593,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6317,7 +6657,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -6338,7 +6678,7 @@ "n": { "df": 3, "docs": { - "21": { + "25": { "tf": 1.0 }, "3": { @@ -6543,8 +6883,26 @@ "17": { "tf": 1.0 }, + "24": { + "tf": 1.0 + } + } + } + }, + "x": { + "df": 0, + "docs": {}, + "t": { + "df": 3, + "docs": { "20": { "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 } } }