<commit_before>use std::fmt;
use std::path;

use log::debug;
use serde::Serialize;
use serde_yaml;

use crate::error::*;

use super::assets;
use super::collection;
use super::mark;
use super::site;
use super::template;
use super::vwiki;
use crate::SyntaxHighlight;

#[derive(Debug, Clone, Serialize)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
    pub source: path::PathBuf,
    pub destination: path::PathBuf,
    pub ignore: Vec<liquid::model::KString>,
    pub page_extensions: Vec<liquid::model::KString>,
    pub include_drafts: bool,
    pub pages: collection::Collection,
    pub posts: collection::Collection,
    pub site: site::Site,
    pub layouts_path: path::PathBuf,
    pub liquid: template::LiquidBuilder,
    pub markdown: mark::MarkdownBuilder,
    pub vimwiki: vwiki::VimwikiBuilder,
    #[serde(skip)]
    pub syntax: std::sync::Arc<SyntaxHighlight>,
    pub assets: assets::AssetsBuilder,
    pub minify: cobalt_config::Minify,
}

impl Config {
    pub fn from_config(source: cobalt_config::Config) -> Result<Self> {
        let cobalt_config::Config {
            root,
            source,
            destination,
            abs_dest,
            include_drafts,
            default,
            pages,
            posts,
            site,
            template_extensions,
            ignore: custom_ignore,
            syntax_highlight,
            layouts_dir,
            includes_dir,
            assets,
            minify,
        } = source;

        if include_drafts {
            debug!("Draft mode enabled");
        }

        if template_extensions.is_empty() {
            failure::bail!("`template_extensions` should not be empty.");
        }

        let source = source.to_path(&root);
        let destination = abs_dest.unwrap_or_else(|| destination.to_path(root));

        let pages = collection::Collection::from_page_config(pages, &site, &default)?;

        let posts =
            collection::Collection::from_post_config(posts, &site, include_drafts, &default)?;

        let site = site::Site::from_config(site);

        let mut ignore: Vec<liquid::model::KString> = vec![".*".into(), "_*".into()];
        if let Ok(rel_dest) = path::Path::new(&destination).strip_prefix(&source) {
            let rel_dest = rel_dest.to_str().expect("started as a utf-8 string");
            if !rel_dest.is_empty() {
                ignore.push(format!("/{}", rel_dest.to_owned()).into());
            }
        }
        ignore.push(format!("/{}", includes_dir).into());
        ignore.push(format!("/{}", layouts_dir).into());
        ignore.push("/_defaults".into());
        ignore.push(format!("/{}", assets.sass.import_dir).into());
        assert_eq!(pages.dir, "");
        assert_eq!(pages.drafts_dir, None);
        ignore.push(format!("!/{}", posts.dir).into());
        if let Some(dir) = posts.drafts_dir.as_deref() {
            ignore.push(format!("!/{}", dir).into());
        }
        ignore.extend(custom_ignore);

        let assets = assets::AssetsBuilder::from_config(assets, &source);

        let includes_path = source.join(includes_dir);
        let layouts_path = source.join(layouts_dir);

        let syntax = std::sync::Arc::new(SyntaxHighlight::new());

        let liquid = template::LiquidBuilder {
            includes_path,
            syntax: syntax.clone(),<commit_msg>load custom syntaxes in config<commit_after>use std::fmt;
use std::path;

use log::debug;
use serde::Serialize;
use serde_yaml;

use crate::error::*;

use super::assets;
use super::collection;
use super::mark;
use super::site;
use super::template;
use super::vwiki;
use crate::SyntaxHighlight;

#[derive(Debug, Clone, Serialize)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
    pub source: path::PathBuf,
    pub destination: path::PathBuf,
    pub ignore: Vec<liquid::model::KString>,
    pub page_extensions: Vec<liquid::model::KString>,
    pub include_drafts: bool,
    pub pages: collection::Collection,
    pub posts: collection::Collection,
    pub site: site::Site,
    pub layouts_path: path::PathBuf,
    pub liquid: template::LiquidBuilder,
    pub markdown: mark::MarkdownBuilder,
    pub vimwiki: vwiki::VimwikiBuilder,
    #[serde(skip)]
    pub syntax: std::sync::Arc<SyntaxHighlight>,
    pub assets: assets::AssetsBuilder,
    pub minify: cobalt_config::Minify,
}

impl Config {
    pub fn from_config(source: cobalt_config::Config) -> Result<Self> {
        let cobalt_config::Config {
            root,
            source,
            destination,
            abs_dest,
            include_drafts,
            default,
            pages,
            posts,
            site,
            template_extensions,
            ignore: custom_ignore,
            syntax_highlight,
            layouts_dir,
            includes_dir,
            assets,
            minify,
        } = source;

        if include_drafts {
            debug!("Draft mode enabled");
        }

        if template_extensions.is_empty() {
            failure::bail!("`template_extensions` should not be empty.");
        }

        let source = source.to_path(&root);
        let destination = abs_dest.unwrap_or_else(|| destination.to_path(root));

        let pages = collection::Collection::from_page_config(pages, &site, &default)?;

        let posts =
            collection::Collection::from_post_config(posts, &site, include_drafts, &default)?;

        let site = site::Site::from_config(site);

        let mut ignore: Vec<liquid::model::KString> = vec![".*".into(), "_*".into()];
        if let Ok(rel_dest) = path::Path::new(&destination).strip_prefix(&source) {
            let rel_dest = rel_dest.to_str().expect("started as a utf-8 string");
            if !rel_dest.is_empty() {
                ignore.push(format!("/{}", rel_dest.to_owned()).into());
            }
        }
        ignore.push(format!("/{}", includes_dir).into());
        ignore.push(format!("/{}", layouts_dir).into());
        ignore.push("/_defaults".into());
        ignore.push(format!("/{}", assets.sass.import_dir).into());
        assert_eq!(pages.dir, "");
        assert_eq!(pages.drafts_dir, None);
        ignore.push(format!("!/{}", posts.dir).into());
        if let Some(dir) = posts.drafts_dir.as_deref() {
            ignore.push(format!("!/{}", dir).into());
        }
        ignore.extend(custom_ignore);

        let assets = assets::AssetsBuilder::from_config(assets, &source);

        let includes_path = source.join(includes_dir);
        let layouts_path = source.join(layouts_dir);

        let mut highlight = SyntaxHighlight::new();
        let syntaxes_path = source.join("_syntaxes");
        if syntaxes_path.exists() {
            highlight.load_custom_syntaxes(&syntaxes_path);
        }

        let syntax = std::sync::Arc::new(highlight);

        let liquid = template::LiquidBuilder {
            includes_path,
            syntax: syntax.clone(),
{'fraction_non_alphanumeric': 0.14285714285714285, 'fraction_numerical': 0.00028830906732016723, 'mean_word_length': 2.672842773954473, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1974697', 'n_tokens_mistral': 2068, 'n_tokens_neox': 2022, 'n_words': 411}