extern crate core; use comrak::{markdown_to_html_with_plugins, parse_document, ComrakOptions}; use magnus::{define_module, function, r_hash::ForEach, scan_args, Error, RHash, Symbol, Value}; use node::CommonmarkerNode; use plugins::syntax_highlighting::construct_syntax_highlighter_from_plugin; mod options; use options::iterate_options_hash; mod plugins; use typed_arena::Arena; mod node; mod utils; pub const EMPTY_STR: &str = ""; fn commonmark_parse(args: &[Value]) -> Result { let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?; let (rb_commonmark,): (String,) = args.required; let kwargs = scan_args::get_kwargs::<_, (), (Option,), ()>(args.keywords, &[], &["options"])?; let (rb_options,) = kwargs.optional; let mut comrak_options = ComrakOptions::default(); if let Some(rb_options) = rb_options { rb_options.foreach(|key: Symbol, value: RHash| { iterate_options_hash(&mut comrak_options, key, value)?; Ok(ForEach::Continue) })?; } let arena = Arena::new(); let root = parse_document(&arena, &rb_commonmark, &comrak_options); CommonmarkerNode::new_from_comrak_node(root) } fn commonmark_to_html(args: &[Value]) -> Result { let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?; let (rb_commonmark,): (String,) = args.required; let kwargs = scan_args::get_kwargs::<_, (), (Option, Option), ()>( args.keywords, &[], &["options", "plugins"], )?; let (rb_options, rb_plugins) = kwargs.optional; let comrak_options = match format_options(rb_options) { Ok(options) => options, Err(err) => return Err(err), }; let mut comrak_plugins = comrak::Plugins::default(); let syntect_adapter = match construct_syntax_highlighter_from_plugin(rb_plugins) { Ok(Some(adapter)) => Some(adapter), Ok(None) => None, Err(err) => return Err(err), }; match syntect_adapter { Some(ref adapter) => comrak_plugins.render.codefence_syntax_highlighter = Some(adapter), None => comrak_plugins.render.codefence_syntax_highlighter = None, } Ok(markdown_to_html_with_plugins( &rb_commonmark, &comrak_options, &comrak_plugins, )) } fn format_options<'c>(rb_options: Option) -> Result, magnus::Error> { let mut comrak_options = ComrakOptions::default(); if let Some(rb_options) = rb_options { rb_options.foreach(|key: Symbol, value: RHash| { iterate_options_hash(&mut comrak_options, key, value)?; Ok(ForEach::Continue) })?; } Ok(comrak_options) } #[magnus::init] fn init() -> Result<(), Error> { let m_commonmarker = define_module("Commonmarker")?; m_commonmarker.define_module_function("commonmark_parse", function!(commonmark_parse, -1))?; m_commonmarker .define_module_function("commonmark_to_html", function!(commonmark_to_html, -1))?; node::init(m_commonmarker).expect("cannot define Commonmarker::Node class"); Ok(()) }