#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
extern crate derive_more;
extern crate either;
extern crate gramma;
pub(crate) mod ast;
pub(crate) mod config;
pub(crate) mod document;
pub mod error;
pub(crate) mod escape;
pub(crate) mod inference;
pub(crate) mod output;
pub(crate) mod transform;
pub(crate) mod utils;
use alloc::{borrow::Cow, string::String};
use core::{borrow::Borrow, fmt};
use error::{Errors, InternalError};
use document::Document;
use output::OutputError;
pub use config::{MetadataConfig, OutputConfig, SpecialTagConfig};
pub use error::ConvertError;
#[deprecated]
#[doc(hidden)]
pub use error::{SyntaxError, SyntaxErrorKind};
type Src<'src> = Cow<'src, str>;
pub fn convert<'src>(
src: &'src str,
config: impl Borrow<OutputConfig<'src>>,
) -> Result<String, ConvertError<'src>> {
let mut out = String::new();
convert_to_internal(src, config.borrow(), &mut out, false)?;
Ok(out)
}
pub fn convert_forgiving<'src>(
src: &'src str,
config: impl Borrow<OutputConfig<'src>>,
) -> Result<String, (Option<String>, ConvertError<'src>)> {
let mut out = String::new();
match convert_to_internal(src, config.borrow(), &mut out, true) {
Ok(()) => Ok(out),
Err(err) if out.is_empty() => Err((None, err)),
Err(err) => Err((Some(out), err)),
}
}
pub fn convert_to<'src>(
src: &'src str,
config: impl Borrow<OutputConfig<'src>>,
out: &mut impl fmt::Write,
) -> Result<(), ConvertError<'src>> {
convert_to_internal(src, config.borrow(), out, true)
}
fn convert_to_internal<'src>(
src: &'src str,
config: &OutputConfig<'src>,
out: &mut impl fmt::Write,
forgive: bool,
) -> Result<(), ConvertError<'src>> {
let mut errors = Errors::new(config);
let (Ok(()) | Err(InternalError)) = (|| {
let mut document = Document::parse(src, &mut errors)?;
document = transform::transform_document(document, src, config, &mut errors)?;
if errors.is_empty() || forgive {
output::output_html_to(src, &document, out, config)
.map_err(|e| match e {
OutputError::WriteError(fmt::Error) => ConvertError::Unknown,
})
.or_else(|_| errors.unknown())?;
}
Ok(())
})();
errors.to_convert_error(src)
}