nargo-document 0.0.0

Nargo documentation tool
Documentation
//! 默认主题实现
//! 提供完整的文档站点主题和样式,兼容 VuTeX 配置格式

use super::Theme;
use crate::config::{Config, FooterConfig, NavItem as ConfigNavItem, SidebarItem as ConfigSidebarItem};
use askama::Template;

/// 语言信息
#[derive(Debug, Clone)]
pub struct LocaleInfo {
    /// 语言代码
    pub code: String,
    /// 语言标签
    pub label: String,
    /// 是否为当前语言
    pub is_current: bool,
}

/// 侧边栏组
#[derive(Debug, Clone)]
pub struct SidebarGroup {
    /// 组标题
    pub text: String,
    /// 组内项目
    pub items: Vec<SidebarLink>,
}

/// 侧边栏链接
#[derive(Debug, Clone)]
pub struct SidebarLink {
    /// 链接文本
    pub text: String,
    /// 链接地址
    pub link: String,
}

/// 导航栏项
#[derive(Debug, Clone)]
pub struct NavItem {
    /// 显示文本
    pub text: String,
    /// 链接
    pub link: String,
}

/// 页面模板上下文
#[derive(Debug, Clone, Template)]
#[template(path = "page.html")]
pub struct PageContext {
    /// 页面标题
    pub page_title: String,
    /// 站点标题
    pub site_title: String,
    /// 页面内容
    pub content: String,
    /// 导航栏项目
    pub nav_items: Vec<NavItem>,
    /// 侧边栏组
    pub sidebar_groups: Vec<SidebarGroup>,
    /// 当前页面路径
    pub current_path: String,
    /// 是否有页脚
    pub has_footer: bool,
    /// 是否有页脚消息
    pub has_footer_message: bool,
    /// 页脚消息
    pub footer_message: String,
    /// 是否有页脚版权
    pub has_footer_copyright: bool,
    /// 页脚版权
    pub footer_copyright: String,
    /// 当前语言
    pub current_lang: String,
    /// 可用语言列表
    pub available_locales: Vec<LocaleInfo>,
    /// 相对于根目录的路径前缀
    pub root_path: String,
}

/// 默认主题
#[derive(Clone)]
pub struct DefaultTheme {
    /// 主题配置
    pub config: Config,
}

impl Theme for DefaultTheme {
    fn name(&self) -> &str {
        "default"
    }

    fn render_page(&self, context: &PageContext) -> Result<String, Box<dyn std::error::Error>> {
        <PageContext as Template>::render(context).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()).into())
    }

    fn config(&self) -> &Config {
        &self.config
    }
}

impl DefaultTheme {
    /// 创建新的默认主题实例
    pub fn new(config: Config) -> Result<Self, Box<dyn std::error::Error>> {
        Ok(Self { config })
    }

    /// 获取站点标题
    pub fn site_title(&self) -> &str {
        self.config.title.as_deref().unwrap_or("Nargo Documentation")
    }

    /// 将 ConfigNavItem 转换为主题 NavItem
    pub fn convert_nav_items(items: &[ConfigNavItem]) -> Vec<NavItem> {
        items.iter().filter_map(|item| item.link.as_ref().map(|link| NavItem { text: item.text.clone(), link: link.clone() })).collect()
    }

    /// 将侧边栏配置转换为 SidebarGroup
    pub fn convert_sidebar_groups(sidebar: &std::collections::HashMap<String, Vec<ConfigSidebarItem>>) -> Vec<SidebarGroup> {
        sidebar
            .iter()
            .map(|(group_text, items)| {
                let sidebar_links: Vec<SidebarLink> = items.iter().filter_map(|item| item.link.as_ref().map(|link| SidebarLink { text: item.text.clone(), link: link.clone() })).collect();

                SidebarGroup { text: group_text.clone(), items: sidebar_links }
            })
            .collect()
    }

    /// 获取页脚配置
    pub fn footer_config(&self) -> &Option<FooterConfig> {
        &self.config.theme.footer
    }
}