diff --git a/src/code.rs b/src/code.rs new file mode 100644 index 0000000..dd3dda1 --- /dev/null +++ b/src/code.rs @@ -0,0 +1,138 @@ +use std::{fs::File, io::Read}; + +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_inline_code() -> FnResult> { + Ok(Json(MetaData { + command_name: "$".to_string(), + call_name: "inline_code".to_string(), + argument_types: vec![ + ("src".to_string(), Type::TInline), + ( + "language".to_string(), + Type::TOption(Box::new(Type::TInline)), + ), + ], + return_type: Type::TInline, + })) +} + +#[plugin_fn] +pub fn metadata_block_code() -> FnResult> { + Ok(Json(MetaData { + command_name: "$".to_string(), + call_name: "block_quote".to_string(), + argument_types: vec![ + ("src".to_string(), Type::TInline), + ( + "language".to_string(), + Type::TOption(Box::new(Type::TInline)), + ), + ], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn inline_code(Json(args): Json>) -> FnResult { + if args.len() != 2 { + return Err(WithReturnCode::new( + anyhow::anyhow!( + "Usage: + 1. [std.$ src] + 2. [std.$ src, language]" + ), + 1, + )); + } + let src = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("src must be Value::Text"), + 1, + )) + } + }; + let language = match &args[1] { + Value::TextOption(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("language must be Value::TextOption"), + 1, + )) + } + }; + let file = File::open(src); + if file.is_err() { + return Err(WithReturnCode::new(anyhow::anyhow!("file not found"), 1)); + } + let mut file = file?; + let mut code = String::new(); + if let Err(_) = file.read_to_string(&mut code) { + return Err(WithReturnCode::new( + anyhow::anyhow!("something went wrong reading the file"), + 1, + )); + } + match language { + Some(language) => Ok(format!( + "{}", + language, code + )), + None => Ok(format!("{}", code)), + } +} + +#[plugin_fn] +pub fn block_code(Json(args): Json>) -> FnResult { + if args.len() != 2 { + return Err(WithReturnCode::new( + anyhow::anyhow!( + "Usage: + 1. {{std.$ src}} + 2. {{std.$ src, language}}" + ), + 1, + )); + }; + let src = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("src must be Value::Text"), + 1, + )) + } + }; + let language = match &args[1] { + Value::TextOption(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("language must be Value::TextOption"), + 1, + )) + } + }; + let file = File::open(src); + if file.is_err() { + return Err(WithReturnCode::new(anyhow::anyhow!("file not found"), 1)); + } + let mut file = file?; + let mut code = String::new(); + if let Err(_) = file.read_to_string(&mut code) { + return Err(WithReturnCode::new( + anyhow::anyhow!("something went wrong reading the file"), + 1, + )); + } + match language { + Some(language) => Ok(format!( + "
{}
", + language, code + )), + None => Ok(format!("
{}
", code)), + } +} diff --git a/src/image.rs b/src/image.rs new file mode 100644 index 0000000..2bd4b2a --- /dev/null +++ b/src/image.rs @@ -0,0 +1,70 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_image() -> FnResult> { + Ok(Json(MetaData { + command_name: "img".to_string(), + call_name: "image".to_string(), + argument_types: vec![ + ("src".to_string(), Type::TInline), + ("alt".to_string(), Type::TInline), + ( + "caption".to_string(), + Type::TOption(Box::new(Type::TInline)), + ), + ], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn image(Json(args): Json>) -> FnResult { + if args.len() != 3 { + return Err(WithReturnCode::new( + anyhow::anyhow!( + "Usage: + 1. {{std.img src, alt}} + 2. {{std.img src, alt, caption}}" + ), + 1, + )); + } + let src = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("src must be Value::Text"), + 1, + )) + } + }; + let alt = match &args[1] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("alt must be Value::Text"), + 1, + )) + } + }; + let caption = match &args[2] { + Value::TextOption(to) => to, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("caption must be Value::TextOption"), + 1, + )) + } + }; + match caption { + Some(cap) => Ok(format!( + "
\"{}\"
{}
", + src, alt, cap + )), + None => Ok(format!( + "
\"{}\"", + src, alt + )), + } +} diff --git a/src/lib.rs b/src/lib.rs index db8d87b..8b7b7ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,12 @@ pub mod anchor; pub mod bold; -pub mod headings; +pub mod code; pub mod footnote; +pub mod headings; +pub mod image; pub mod italic; +pub mod list; +pub mod quote; +pub mod rules; +pub mod strike; +pub mod table; diff --git a/src/list.rs b/src/list.rs new file mode 100644 index 0000000..0131130 --- /dev/null +++ b/src/list.rs @@ -0,0 +1,84 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_unordered_list() -> FnResult> { + Ok(Json(MetaData { + command_name: "-list".to_string(), + call_name: "unordered_list".to_string(), + argument_types: vec![("elems".to_string(), Type::TArray(Box::new(Type::TInline)))], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn metadata_ordered_list() -> FnResult> { + Ok(Json(MetaData { + command_name: "#list".to_string(), + call_name: "ordered_list".to_string(), + argument_types: vec![("elems".to_string(), Type::TArray(Box::new(Type::TInline)))], + return_type: Type::TBlock, + })) +} + +fn is_list(text: &str) -> bool { + let is_unordered_list = text.starts_with("
    ") && text.ends_with("
"); + let is_ordered_list = text.starts_with("
    ") && text.ends_with("
"); + return is_unordered_list && is_ordered_list; +} + +#[plugin_fn] +pub fn unordered_list(Json(args): Json>) -> FnResult { + if args.len() != 1 { + return Err(WithReturnCode::new( + anyhow::anyhow!("Usage: {{std.-list elem1, elem2, ..., elemN}}"), + 1, + )); + } + let elems = match &args[0] { + Value::TextArray(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("elems must be Value::TextArray"), + 1, + )) + } + }; + let mut result = String::new(); + for elem in elems { + if is_list(elem) { + result += elem; + continue; + } + result += &format!("
  • {}
  • ", elem); + } + Ok(format!("
      {}
    ", result)) +} + +#[plugin_fn] +pub fn ordered_list(Json(args): Json>) -> FnResult { + if args.len() != 1 { + return Err(WithReturnCode::new( + anyhow::anyhow!("Usage: {{std.#list elem1, elem2, ..., elemN}}"), + 1, + )); + } + let elems = match &args[0] { + Value::TextArray(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("elems must be Value::TextArray"), + 1, + )) + } + }; + let mut result = String::new(); + for elem in elems { + if is_list(elem) { + result += elem; + continue; + } + result += &format!("
  • {}
  • ", elem); + } + Ok(format!("
      {}
    ", result)) +} diff --git a/src/quote.rs b/src/quote.rs new file mode 100644 index 0000000..afec40b --- /dev/null +++ b/src/quote.rs @@ -0,0 +1,103 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_inline_quote() -> FnResult> { + Ok(Json(MetaData { + command_name: ">".to_string(), + call_name: "inline_quote".to_string(), + argument_types: vec![ + ("text".to_string(), Type::TInline), + ("cite".to_string(), Type::TOption(Box::new(Type::TInline))), + ], + return_type: Type::TInline, + })) +} + +#[plugin_fn] +pub fn metadata_block_quote() -> FnResult> { + Ok(Json(MetaData { + command_name: ">".to_string(), + call_name: "block_quote".to_string(), + argument_types: vec![ + ("text".to_string(), Type::TInline), + ("cite".to_string(), Type::TOption(Box::new(Type::TInline))), + ], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn inline_quote(Json(args): Json>) -> FnResult { + if args.len() != 2 { + return Err(WithReturnCode::new( + anyhow::anyhow!( + "Usage: + 1. [std.> text] + 2. [std.> text, cite]" + ), + 1, + )); + } + let text = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("text must be Value::Text"), + 1, + )) + } + }; + let cite = match &args[1] { + Value::TextOption(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("text must be Value::TextOption"), + 1, + )) + } + }; + match cite { + Some(cite) => Ok(format!("{}", cite, text)), + None => Ok(format!("{}", text)), + } +} + +#[plugin_fn] +pub fn block_quote(Json(args): Json>) -> FnResult { + if args.len() != 2 { + return Err(WithReturnCode::new( + anyhow::anyhow!( + "Usage: + 1. {{std.> text}} + 2. {{std.> text, cite}}" + ), + 1, + )); + }; + let text = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("text must be Value::Text"), + 1, + )) + } + }; + let cite = match &args[1] { + Value::TextOption(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("text must be Value::TextOption"), + 1, + )) + } + }; + match cite { + Some(cite) => Ok(format!( + "
    {}
    ", + cite, text + )), + None => Ok(format!("
    {}
    ", text)), + } +} diff --git a/src/rules.rs b/src/rules.rs new file mode 100644 index 0000000..4d6c38b --- /dev/null +++ b/src/rules.rs @@ -0,0 +1,20 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_rules() -> FnResult> { + Ok(Json(MetaData { + command_name: "---".to_string(), + call_name: "rules".to_string(), + argument_types: vec![], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn rules(Json(args): Json>) -> FnResult { + if args.len() != 0 { + return Err(WithReturnCode::new(anyhow::anyhow!("Usage: {{std.---}}"), 1)); + } + Ok(String::from("
    ")) +} diff --git a/src/strike.rs b/src/strike.rs new file mode 100644 index 0000000..c072803 --- /dev/null +++ b/src/strike.rs @@ -0,0 +1,29 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_strike() -> FnResult> { + Ok(Json(MetaData { + command_name: "~".to_string(), + call_name: "strike".to_string(), + argument_types: vec![("text".to_string(), Type::TInline)], + return_type: Type::TInline, + })) +} + +#[plugin_fn] +pub fn strike(Json(args): Json>) -> FnResult { + if args.len() != 1 { + return Err(WithReturnCode::new(anyhow::anyhow!("Usage: [~ text]"), 1)); + } + let text = match &args[0] { + Value::Text(t) => t, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("text must be Value::Text"), + 1, + )) + } + }; + Ok(format!("{}", text)) +} diff --git a/src/table.rs b/src/table.rs new file mode 100644 index 0000000..48430cc --- /dev/null +++ b/src/table.rs @@ -0,0 +1,56 @@ +use brack_sdk_rs::{MetaData, Type, Value}; +use extism_pdk::{plugin_fn, FnResult, Json, WithReturnCode}; + +#[plugin_fn] +pub fn metadata_table() -> FnResult> { + Ok(Json(MetaData { + command_name: "table".to_string(), + call_name: "table".to_string(), + argument_types: vec![ + ("col".to_string(), Type::TInline), + ("elems".to_string(), Type::TArray(Box::new(Type::TInline))), + ], + return_type: Type::TBlock, + })) +} + +#[plugin_fn] +pub fn table(Json(args): Json>) -> FnResult { + if args.len() != 2 { + return Err(WithReturnCode::new( + anyhow::anyhow!("Usage: {{std.table col, elems}}"), + 1, + )); + } + let col = match &args[0] { + Value::Text(t) => t.parse::(), + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("col must be Value::Text"), + 1, + )) + } + }; + let col = match col { + Ok(c) => c, + Err(err) => return Err(WithReturnCode::new(anyhow::anyhow!(err), 1)), + }; + let elems = match &args[1] { + Value::TextArray(ta) => ta, + _ => { + return Err(WithReturnCode::new( + anyhow::anyhow!("elems must be Value::TextArray"), + 1, + )) + } + }; + let mut result = String::from(""); + for i in 0..(elems.len() as i32 % col) { + let mut tr = String::from(""); + for j in 0..col { + tr += &format!("{}", elems[(i * col + j) as usize]); + } + result += &format!("{}", tr); + } + Ok(format!("{}
    ", result)) +}