Switch to pulldown-cmark for markdown parsing + Try to parse mentions

It's not working correctly yet for some reason…
This commit is contained in:
Bat
2018-06-20 15:29:19 +01:00
parent b9951f0d70
commit 4ea071e709
5 changed files with 66 additions and 143 deletions
+1 -1
View File
@@ -8,7 +8,6 @@ extern crate base64;
extern crate bcrypt;
extern crate chrono;
extern crate colored;
extern crate comrak;
extern crate failure;
#[macro_use]
extern crate failure_derive;
@@ -23,6 +22,7 @@ extern crate dotenv;
#[macro_use]
extern crate lazy_static;
extern crate openssl;
extern crate pulldown_cmark;
extern crate reqwest;
extern crate rocket;
extern crate rocket_contrib;
+1 -14
View File
@@ -1,4 +1,3 @@
use comrak::{markdown_to_html, ComrakOptions};
use heck::KebabCase;
use rocket::request::Form;
use rocket::response::{Redirect, Flash};
@@ -88,19 +87,7 @@ fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn)
if slug == "new" || Post::find_by_slug(&*conn, slug.clone(), blog.id).is_some() {
Redirect::to(uri!(new: blog = blog_name))
} else {
let content = markdown_to_html(form.content.to_string().as_ref(), &ComrakOptions{
smart: true,
safe: true,
ext_strikethrough: true,
ext_tagfilter: true,
ext_table: true,
ext_autolink: true,
ext_tasklist: true,
ext_superscript: true,
ext_header_ids: Some("title".to_string()),
ext_footnotes: true,
..ComrakOptions::default()
});
let content = utils::md_to_html(form.content.to_string().as_ref());
let post = Post::insert(&*conn, NewPost {
blog_id: blog.id,
+53
View File
@@ -1,5 +1,6 @@
use gettextrs::gettext;
use heck::CamelCase;
use pulldown_cmark::{Event, Parser, Options, Tag, html};
use rocket::{
http::uri::Uri,
response::{Redirect, Flash}
@@ -18,3 +19,55 @@ pub fn make_actor_id(name: String) -> String {
pub fn requires_login(message: &str, url: Uri) -> Flash<Redirect> {
Flash::new(Redirect::to(Uri::new(format!("/login?m={}", gettext(message.to_string())))), "callback", url.as_str())
}
pub fn md_to_html(md: &str) -> String {
let parser = Parser::new_ext(md, Options::all());
let parser = parser.flat_map(|evt| match evt {
Event::Text(txt) => txt.chars().fold((vec![], false, String::new(), 0), |(mut events, in_mention, text_acc, n), c| {
if in_mention {
if c.is_alphanumeric() || c == '@' || c == '.' || c == '-' || c == '_' {
(events, in_mention, text_acc + c.to_string().as_ref(), n + 1)
} else {
let short_mention = text_acc.clone();
let short_mention = short_mention.splitn(1, '@').nth(0).unwrap_or("");
let link = Tag::Link(format!("/@/{}/", text_acc).into(), short_mention.to_string().into());
events.push(Event::Start(link.clone()));
events.push(Event::Text(format!("@{}", short_mention).into()));
events.push(Event::End(link));
(events, false, c.to_string(), n + 1)
}
} else {
if c == '@' {
events.push(Event::Text(text_acc.into()));
(events, true, String::new(), n + 1)
} else {
if n >= (txt.len() - 1) { // Add the text after at the end, even if it is not followed by a mention.
events.push(Event::Text((text_acc.clone() + c.to_string().as_ref()).into()))
}
(events, in_mention, text_acc + c.to_string().as_ref(), n + 1)
}
}
}).0,
_ => vec![evt]
});
let mut buf = String::new();
html::push_html(&mut buf, parser);
buf
// let root = parse_document(&arena, md, &ComrakOptions{
// smart: true,
// safe: true,
// ext_strikethrough: true,
// ext_tagfilter: true,
// ext_table: true,
// // ext_autolink: true,
// ext_tasklist: true,
// ext_superscript: true,
// ext_header_ids: Some("title".to_string()),
// ext_footnotes: true,
// ..ComrakOptions::default()
// });
}