You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.9KB

  1. extern crate elasticlunr;
  2. #[macro_use]
  3. extern crate lazy_static;
  4. extern crate ammonia;
  5. extern crate errors;
  6. extern crate content;
  7. use std::collections::{HashMap, HashSet};
  8. use std::path::PathBuf;
  9. use elasticlunr::Index;
  10. use content::Section;
  11. pub const ELASTICLUNR_JS: &'static str = include_str!("elasticlunr.min.js");
  12. lazy_static! {
  13. static ref AMMONIA: ammonia::Builder<'static> = {
  14. let mut clean_content = HashSet::new();
  15. clean_content.insert("script");
  16. clean_content.insert("style");
  17. let mut builder = ammonia::Builder::new();
  18. builder
  19. .tags(HashSet::new())
  20. .tag_attributes(HashMap::new())
  21. .generic_attributes(HashSet::new())
  22. .link_rel(None)
  23. .allowed_classes(HashMap::new())
  24. .clean_content_tags(clean_content);
  25. builder
  26. };
  27. }
  28. /// Returns the generated JSON index with all the documents of the site added
  29. /// TODO: is making `in_search_index` apply to subsections of a `false` section useful?
  30. pub fn build_index(sections: &HashMap<PathBuf, Section>) -> String {
  31. let mut index = Index::new(&["title", "body"]);
  32. for section in sections.values() {
  33. add_section_to_index(&mut index, section);
  34. }
  35. index.to_json()
  36. }
  37. fn add_section_to_index(index: &mut Index, section: &Section) {
  38. if !section.meta.in_search_index {
  39. return;
  40. }
  41. // Don't index redirecting sections
  42. if section.meta.redirect_to.is_none() {
  43. index.add_doc(
  44. &section.permalink,
  45. &[&section.meta.title.clone().unwrap_or(String::new()), &AMMONIA.clean(&section.content).to_string()],
  46. );
  47. }
  48. for page in &section.pages {
  49. if !page.meta.in_search_index {
  50. continue;
  51. }
  52. index.add_doc(
  53. &page.permalink,
  54. &[&page.meta.title.clone().unwrap_or(String::new()), &AMMONIA.clean(&page.content).to_string()],
  55. );
  56. }
  57. }