From 82488606f81438647043b834243ba4003a229911 Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L. de Mello" Date: Thu, 28 Mar 2024 17:34:49 -0300 Subject: [PATCH] feat: basic markdown text to npf conversion --- src/convert.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 7 +++++- src/utils.rs | 24 ++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/convert.rs b/src/convert.rs index 0c9cc6a..d65777d 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -1,7 +1,73 @@ +use comrak::{arena_tree::Node, nodes::Ast, nodes::NodeValue}; +use std::{cell::RefCell, fmt::Error}; + +use crate::utils; + mod npf; +use npf::{ + content_types::{self, text::Formatting, text::FormattingType}, + ContentType, NPF, +}; #[derive(clap::ValueEnum, Clone, Debug)] pub enum Formats { TumblrNPF, } +pub fn to_tumblr_npf<'a>(ast: &'a Node<'a, RefCell>) -> Result, 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::::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::Text(t) => text.push_str(&format!("{} ", &t)), + _ => (), + } + }); + + let mut block = + content_types::Text::from(text.borrow().trim().to_string().replace(" ", " ")); + block.formating = if formatting.borrow().len() > 0 { + Some(formatting.borrow().to_vec()) + } else { + None + }; + + npf.borrow_mut().content.push(ContentType::Text(block)); + } + _ => (), + }); + + Ok(npf) +} diff --git a/src/main.rs b/src/main.rs index 64eefbf..a1bcd68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use core::panic; +use std::borrow::Borrow; use clap::{ArgAction, Parser, Subcommand}; use clio::*; @@ -48,7 +49,6 @@ enum Commands { #[command(subcommand)] command: FrontmatterCommands, }, - Not {}, Convert { #[arg(short, long)] format: convert::Formats, @@ -87,8 +87,13 @@ fn main() { let ast = comrak::parse_document(&arena, &file, &mdparser::utils::default_options()); if let Commands::Convert { format } = &cli.command { + let r = match format { + convert::Formats::TumblrNPF => convert::to_tumblr_npf(&ast), + }; + println!("{:#?}", r.borrow()); return; } + match &cli.command { Commands::Links { path_root, diff --git a/src/utils.rs b/src/utils.rs index 3d8cccb..fa6beab 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,7 @@ +use std::cell::RefCell; + +use comrak::nodes::NodeValue; + pub fn default_options() -> comrak::Options { let mut opts = comrak::Options::default(); @@ -20,6 +24,26 @@ where } } +pub fn iter_nodes_shallow<'a, F>(node: &'a comrak::nodes::AstNode<'a>, f: &F) +where + F: Fn(&'a comrak::nodes::AstNode<'a>), +{ + for c in node.children() { + f(c) + } +} + +pub fn extract_text<'a>(node: &'a comrak::nodes::AstNode<'a>) -> String { + let text = RefCell::new(String::new()); + iter_nodes(node, &|node| { + if let NodeValue::Text(t) = &node.data.borrow().value { + text.borrow_mut().push_str(&t); + } + }); + let r = text.borrow().to_string(); + r +} + pub fn iter_nodes_r<'a, F, T>(node: &'a comrak::nodes::AstNode<'a>, f: &F) -> Option where F: Fn(&'a comrak::nodes::AstNode<'a>) -> Option,