Skip to content

Commit

Permalink
Add discord formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Noskcaj19 committed Jul 18, 2018
1 parent 512a713 commit 3d460f1
Show file tree
Hide file tree
Showing 12 changed files with 311 additions and 6 deletions.
36 changes: 31 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ crate-type = ["dylib"]
libc = "0.2.42"
serenity = { git = "https://github.com/Noskcaj19/serenity" }
lazy_static = "1.0.2"

[dependencies.parsing]
path = "parsing"
2 changes: 2 additions & 0 deletions parsing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
**/*.rs.bk
7 changes: 7 additions & 0 deletions parsing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "parsing"
version = "0.1.0"
authors = ["Noskcaj <[email protected]>"]

[dependencies]
nom = "4.0.0"
3 changes: 3 additions & 0 deletions parsing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Parsing

Sub-crate to handle text parsing for weechat-discord
170 changes: 170 additions & 0 deletions parsing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#[macro_use]
extern crate nom;

/*
Italics *italics* or _italics_
Bold **bold**
Underline italics __*underline italics*__
Underline bold __**underline bold**__
Bold Italics ***bold italics***
underline bold italics __***underline bold italics***__
Underline __underline__
Strikethrough ~~Strikethrough~~
*/

use nom::anychar;
use nom::types::CompleteStr;

// TODO: Support nested styles
#[derive(Debug, PartialEq)]
pub enum Style {
Text(String),
Code(String),
Bold(String),
Italic(String),
BoldItalics(String),
Underline(String),
UnderlineBold(String),
UnderlineItalics(String),
UnderlineBoldItalics(String),
Strikethrough(String),
}

use self::Style::*;

named!(code<CompleteStr, Style>,
map!(
delimited!(tag!("`"), take_until!("`"), tag!("`")),
|text| Code(text.0.to_owned())
)
);

named!(star_italic<CompleteStr, Style>,
map!(
delimited!(tag!("*"), take_until!("*"), tag!("*")),
|text| Italic(text.0.to_owned())
)
);

named!(underscore_italic<CompleteStr, Style>,
map!(
delimited!(tag!("_"), take_until!("_"), tag!("_")),
|text| Italic(text.0.to_owned())
)
);

named!(italic<CompleteStr, Style>,
alt_complete!(star_italic | underscore_italic)
);

named!(bold<CompleteStr, Style>,
map!(
delimited!(tag!("**"), take_until!("**"), tag!("**")),
|text| Bold(text.0.to_owned())
)
);

named!(underline<CompleteStr, Style>,
map!(
delimited!(tag!("__"), take_until!("__"), tag!("__")),
|text| Underline(text.0.to_owned())
)
);

named!(strikethrough<CompleteStr, Style>,
map!(
delimited!(tag!("~~"), take_until!("~~"), tag!("~~")),
|text| Strikethrough(text.0.to_owned())
)
);

named!(styled<CompleteStr, Style>, alt!(bold | underline | italic | strikethrough | code));

named!(maybe_style<CompleteStr, Style>,
alt!(
styled |
map!(
many_till!(call!(anychar), alt!(recognize!(peek!(styled)) | eof!())),
|chars| Text(chars.0.iter().collect())
)
)
);

named!(text<CompleteStr, Vec<Style>>,
many0!(maybe_style)
);

pub fn parse_msg(msg: &str) -> Option<Vec<Style>> {
match text(CompleteStr(msg)) {
Ok((_, msg)) => Some(msg),
_ => None,
}
}

#[cfg(test)]
mod test {
use super::*;

macro_rules! style {
($style:ident($text:tt)) => {
$style($text.to_owned())
};
}

macro_rules! parse {
($parser:ident($str:tt)) => {
$parser(CompleteStr($str)).unwrap().1
};
}

#[test]
fn italic_underline() {
assert_eq!(parse!(italic("_italic_")), style!(Italic("italic")));
}

#[test]
fn italic_star() {
assert_eq!(parse!(italic("*italic*")), style!(Italic("italic")));
}

#[test]
fn bold_test() {
assert_eq!(parse!(bold("**bold**")), style!(Bold("bold")));
}

#[test]
fn underline_test() {
assert_eq!(
parse!(underline("__underline__")),
style!(Underline("underline")),
);
}

#[test]
fn strikethrough_test() {
assert_eq!(
parse!(strikethrough("~~strikethrough~~")),
style!(Strikethrough("strikethrough")),
);
}

#[test]
fn variety() {
assert_eq!(
parse!(text(
"_italic_ **bold** *italic* __underline__ ~~strikethrough~~"
)),
[
style!(Italic("italic")),
style!(Text(" ")),
style!(Bold("bold")),
style!(Text(" ")),
style!(Italic("italic")),
style!(Text(" ")),
style!(Underline("underline")),
style!(Text(" ")),
style!(Strikethrough("strikethrough")),
]
);
}
}
8 changes: 7 additions & 1 deletion src/discord/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use serenity::model::prelude::*;
use serenity::prelude::*;
use serenity::CACHE;

use super::formatting;

pub struct Handler();

impl EventHandler for Handler {
Expand Down Expand Up @@ -38,7 +40,11 @@ impl EventHandler for Handler {

buffer.print_tags(
&tags,
&format!("{}\t{}", msg.author.name, msg.content_safe()),
&format!(
"{}\t{}",
msg.author.name,
formatting::discord_to_weechat(&msg.content_safe())
),
);
}
}
Expand Down
70 changes: 70 additions & 0 deletions src/discord/formatting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use ffi::color_codes;
use parsing::{self, Style};

pub fn discord_to_weechat(msg: &str) -> String {
let ast = parsing::parse_msg(msg).unwrap_or_else(|| Vec::new());
let mut result = String::new();
for node in ast {
match node {
Style::Text(txt) => result.push_str(&txt),
Style::Code(code) => {
result.push_str(&color_codes("/grey"));
result.push_str(&code);
result.push_str(&color_codes("reset"));
}
Style::Bold(bold) => {
result.push_str(&color_codes("bold"));
result.push_str(&bold);
result.push_str(&color_codes("-bold"));
}
Style::Italic(italic) => {
result.push_str(&color_codes("italic"));
result.push_str(&italic);
result.push_str(&color_codes("-italic"));
}
Style::BoldItalics(bold_italic) => {
result.push_str(&color_codes("bold"));
result.push_str(&color_codes("italic"));
result.push_str(&bold_italic);
result.push_str(&color_codes("-bold"));
result.push_str(&color_codes("-italic"));
}
Style::Underline(under) => {
result.push_str(&color_codes("underline"));
result.push_str(&under);
result.push_str(&color_codes("-underline"));
}
Style::UnderlineBold(under_bold) => {
result.push_str(&color_codes("bold"));
result.push_str(&color_codes("underline"));
result.push_str(&under_bold);
result.push_str(&color_codes("-bold"));
result.push_str(&color_codes("-underline"));
}
Style::UnderlineItalics(under_italics) => {
result.push_str(&color_codes("italic"));
result.push_str(&color_codes("underline"));
result.push_str(&under_italics);
result.push_str(&color_codes("-italic"));
result.push_str(&color_codes("-underline"));
}
Style::UnderlineBoldItalics(under_bold_italics) => {
result.push_str(&color_codes("italic"));
result.push_str(&color_codes("bold"));
result.push_str(&color_codes("underline"));
result.push_str(&under_bold_italics);
result.push_str(&color_codes("-italic"));
result.push_str(&color_codes("-bold"));
result.push_str(&color_codes("-underline"));
}
Style::Strikethrough(strikethrough) => {
result.push_str(&color_codes("red"));
result.push_str("~~");
result.push_str(&strikethrough);
result.push_str("~~");
result.push_str(&color_codes("resetcolor"));
}
}
}
result
}
Loading

0 comments on commit 3d460f1

Please sign in to comment.