94 lines · 2.7 KB · Rust
RawDownload
use anyhow::Result;use mdbook::book::{Book, BookItem};use mdbook::errors::Error;use mdbook::preprocess::{Preprocessor, PreprocessorContext as MdBookContext};use settings::KeymapFile;use std::sync::Arc;use util::asset_str; mod templates; use templates::{ActionTemplate, KeybindingTemplate, Template}; pub struct PreprocessorContext {    macos_keymap: Arc<KeymapFile>,    linux_keymap: Arc<KeymapFile>,} impl PreprocessorContext {    pub fn new() -> Result<Self> {        let macos_keymap = Arc::new(load_keymap("keymaps/default-macos.json")?);        let linux_keymap = Arc::new(load_keymap("keymaps/default-linux.json")?);        Ok(Self {            macos_keymap,            linux_keymap,        })    }     pub fn find_binding(&self, os: &str, action: &str) -> Option<String> {        let keymap = match os {            "macos" => &self.macos_keymap,            "linux" => &self.linux_keymap,            _ => return None,        };         // Find the binding in reverse order, as the last binding takes precedence.        keymap.sections().rev().find_map(|section| {            section.bindings().rev().find_map(|(keystroke, a)| {                if a.to_string() == action {                    Some(keystroke.to_string())                } else {                    None                }            })        })    }} fn load_keymap(asset_path: &str) -> Result<KeymapFile> {    let content = asset_str::<settings::SettingsAssets>(asset_path);    KeymapFile::parse(content.as_ref())} pub struct ZedDocsPreprocessor {    context: PreprocessorContext,    templates: Vec<Box<dyn Template>>,} impl ZedDocsPreprocessor {    pub fn new() -> Result<Self> {        let context = PreprocessorContext::new()?;        let templates: Vec<Box<dyn Template>> = vec![            Box::new(KeybindingTemplate::new()),            Box::new(ActionTemplate::new()),        ];        Ok(Self { context, templates })    }     fn process_content(&self, content: &str) -> String {        let mut processed = content.to_string();        for template in &self.templates {            processed = template.process(&self.context, &processed);        }        processed    }} impl Preprocessor for ZedDocsPreprocessor {    fn name(&self) -> &str {        "zed-docs-preprocessor"    }     fn run(&self, _ctx: &MdBookContext, mut book: Book) -> Result<Book, Error> {        book.for_each_mut(|item| {            if let BookItem::Chapter(chapter) = item {                chapter.content = self.process_content(&chapter.content);            }        });        Ok(book)    }     fn supports_renderer(&self, renderer: &str) -> bool {        renderer != "not-supported"    }}