nmd-core 1.0.1

Official NMD compiler core
Documentation
use getset::{Getters, Setters};
use serde::Serialize;
use crate::{codex::{modifier::ModifiersBucket, Codex}, compilable_text::{compilable_text_part::{CompilableTextPart, CompilableTextPartType}, CompilableText}, compilation::{compilable::Compilable, compilation_configuration::{compilation_configuration_overlay::CompilationConfigurationOverLay, CompilationConfiguration}, compilation_error::CompilationError, compilation_outcome::CompilationOutcome}, output_format::OutputFormat, resource::resource_reference::ResourceReference, utility::nmd_unique_identifier::NmdUniqueIdentifier};


#[derive(Debug, Clone, Serialize)]
pub enum HeadingLevel {
    Explicit(u32),
    Minor,
    Major,
    Same
}


#[derive(Debug, Getters, Setters, Clone, Serialize)]
pub struct Heading {

    #[getset(get = "pub", set = "pub")]
    level: HeadingLevel,

    #[getset(get = "pub", set = "pub")]
    title: String,

    #[getset(get = "pub", set = "pub")]
    resource_reference: Option<ResourceReference>,

    #[getset(get = "pub", set = "pub")]
    nuid: Option<NmdUniqueIdentifier>,
}

impl Heading {
    pub fn new(level: HeadingLevel, title: String) -> Self {

        Self {
            level,
            title,
            resource_reference: None,
            nuid: None,
        }
    }
}

impl Compilable for Heading {
    fn standard_compile(&mut self, format: &OutputFormat, codex: &Codex, compilation_configuration: &CompilationConfiguration, compilation_configuration_overlay: CompilationConfigurationOverLay) -> Result<CompilationOutcome, CompilationError> {
        
        let document_name = compilation_configuration_overlay.document_name().as_ref();

        if document_name.is_none() {
            return Err(CompilationError::DocumentNameNotFound)
        }

        let document_name = document_name.unwrap();

        let id: ResourceReference = ResourceReference::of_internal_from_without_sharp(&self.title, Some(&document_name))?;

        let mut compiled_title = CompilableText::from(self.title.clone());
        
        compiled_title.compile(format, codex, compilation_configuration, compilation_configuration_overlay.clone())?;

        let res = match format {
            OutputFormat::Html => {

                let nuid_attr: String;

                if let Some(nuid) = &self.nuid {
                    nuid_attr = format!(r#"data-nuid="{}""#, nuid);
                } else {
                    nuid_attr = String::new();
                }

                let level = match self.level {
                    HeadingLevel::Explicit(l) => l,
                    _ => return Err(CompilationError::HeadingLevelNotInferable(self.title.to_string()))
                };

                let outcome = CompilableText::new(vec![

                    CompilableTextPart::new(
                        format!(r#"<h{} class="heading-{}" id="{}" {}>"#, level, level, id.build_without_internal_sharp(), nuid_attr),
                        CompilableTextPartType::Fixed
                    ),
                    CompilableTextPart::new(
                        compiled_title.content(),
                        CompilableTextPartType::Compilable{ incompatible_modifiers: ModifiersBucket::None }
                    ),
                    CompilableTextPart::new(
                        format!(r#"</h{}>"#, level),
                        CompilableTextPartType::Fixed
                    ),
                ]);

                outcome
            },
        };

        self.set_resource_reference(Some(id));      // TODO: is pointless?

        Ok(CompilationOutcome::from(&res))
    }
}