This repository has been archived on 2025-10-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
mdparser/src/convert.rs
Gustavo "Guz" L. de Mello 473a02de1b fix: handle errors
2024-04-02 12:35:46 -03:00

168 lines
6.3 KiB
Rust

use comrak::{arena_tree::Node, nodes::Ast, nodes::NodeValue};
use std::{cell::RefCell, fmt::Error};
use crate::utils;
mod npf;
use npf::content_types::text::{Formatting, FormattingType, Subtypes};
use npf::{content_types, ContentType, NPF};
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Formats {
TumblrNPF,
}
pub fn to_tumblr_npf<'a>(ast: &'a Node<'a, RefCell<Ast>>) -> Result<RefCell<NPF>, Error> {
let npf = RefCell::new(NPF::<'a>::new());
utils::iter_nodes_shallow(ast, &|node| match &node.data.borrow().value {
NodeValue::Paragraph => {
let text = RefCell::new(String::new());
let formatting = RefCell::new(Vec::<Formatting>::new());
utils::iter_nodes_shallow(node, &|node| {
let mut text = text.borrow_mut();
let mut formatting = formatting.borrow_mut();
match &node.data.borrow().value {
NodeValue::Link(l) => {
let t = utils::extract_text(node);
formatting.push(Formatting {
r#type: FormattingType::Link,
start: text.chars().count(),
end: text.chars().count() + t.chars().count() + 1,
url: Some(String::from(&l.url)),
color: None,
blog: None,
});
text.push_str(&format!("{} ", &t))
}
NodeValue::Strong => {
let t = utils::extract_text(node);
formatting.push(Formatting {
r#type: FormattingType::Bold,
start: text.chars().count(),
end: text.chars().count() + t.chars().count() + 1,
url: None,
color: None,
blog: None,
});
text.push_str(&format!("{} ", &t))
}
NodeValue::Emph => {
let t = utils::extract_text(node);
formatting.push(Formatting {
r#type: FormattingType::Italic,
start: text.chars().count(),
end: text.chars().count() + t.chars().count() + 1,
url: None,
color: None,
blog: None,
});
text.push_str(&format!("{} ", &t))
}
NodeValue::Text(t) => text.push_str(&format!("{} ", &t)),
_ => (),
};
Ok::<(), Error>(())
})?;
let text = text.borrow().trim().to_string().replace(" ", " ");
let mut block = content_types::Text::from(text);
block.formatting = if formatting.borrow().len() > 0 {
Some(formatting.borrow().to_vec())
} else {
None
};
npf.borrow_mut().content.push(ContentType::Text(block));
Ok::<(), Error>(())
}
NodeValue::BlockQuote => {
let block_quote = to_tumblr_npf(node)?;
let final_block = RefCell::new(content_types::Text::new());
block_quote.borrow_mut().content.iter_mut().for_each(|b| {
if let ContentType::Text(t) = b {
let mut fb = final_block.borrow_mut();
let text_len = fb.text.chars().count();
if let Some(formattings) = &t.formatting {
for formatting in formattings {
match fb.formatting {
Some(ref mut v) => v.push(Formatting {
start: text_len + formatting.start,
end: text_len + formatting.end,
..formatting.clone()
}),
None => {
fb.formatting = Some(vec![Formatting {
start: text_len + formatting.start,
end: text_len + formatting.end,
..formatting.clone()
}]);
}
}
}
}
fb.text.push_str(&format!("{}\n\n", &t.text));
} else {
}
});
println!("{node:#?}");
println!("{:#?}", final_block.borrow());
/*
block_quote
.unwrap()
.borrow_mut()
.content
.iter_mut()
.map(|b| {
if let ContentType::Text(ref mut t) = b {
t.subtype = Some(Subtypes::Indented);
}
b
})
.for_each(|b| npf.borrow_mut().content.push(b.clone()));
*/
Ok(())
}
NodeValue::Heading(h) => {
let mut text = content_types::Text::from(utils::extract_text(node));
if h.level == 1 {
text.subtype = Some(Subtypes::Heading1);
} else if h.level == 2 {
text.subtype = Some(Subtypes::Heading2);
} else if h.level == 3 {
text.subtype = Some(Subtypes::UnorderedListItem);
let formatting = Formatting {
r#type: FormattingType::Bold,
start: 0,
end: text.text.chars().count() + 1,
url: None,
color: None,
blog: None,
};
match text.formatting {
Some(ref mut f) => f.push(formatting),
None => text.formatting = Some(vec![formatting]),
};
} else {
text.subtype = Some(Subtypes::UnorderedListItem);
}
npf.borrow_mut().content.push(ContentType::Text(text));
Ok(())
}
_ => Ok(()),
})?;
Ok(npf)
}