Edit blogs, and add blog icons and banners (#460)
Also adds a parameter to `md_to_html` to only render inline elements (so that we don't have titles or images in blog descriptions). And moves the delete button for the blog on the edition page. I still have to update the SQLite migration once others PRs with migrations will be merged. Also, there will be a problem when you edit a blog while not owning its banner or icon: when validating they will be reset to their default values… I don't see a good solution to this until we have a better way to handle uploads with Rocket (the same is probably happening for articles btw). And the icon/banner are not federated yet, I don't know if I should add it to this PR or if it can come after?   Fixes #453 Fixes #454
This commit is contained in:
@@ -46,8 +46,22 @@ enum State {
|
||||
Ready,
|
||||
}
|
||||
|
||||
fn to_inline(tag: Tag) -> Tag {
|
||||
match tag {
|
||||
Tag::Header(_) | Tag::Table(_) | Tag::TableHead | Tag::TableRow | Tag::TableCell => {
|
||||
Tag::Paragraph
|
||||
}
|
||||
Tag::Image(url, title) => Tag::Link(url, title),
|
||||
t => t,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns (HTML, mentions, hashtags)
|
||||
pub fn md_to_html(md: &str, base_url: &str) -> (String, HashSet<String>, HashSet<String>) {
|
||||
pub fn md_to_html(
|
||||
md: &str,
|
||||
base_url: &str,
|
||||
inline: bool,
|
||||
) -> (String, HashSet<String>, HashSet<String>) {
|
||||
let parser = Parser::new_ext(md, Options::all());
|
||||
|
||||
let (parser, mentions, hashtags): (Vec<Event>, Vec<String>, Vec<String>) = parser
|
||||
@@ -69,6 +83,26 @@ pub fn md_to_html(md: &str, base_url: &str) -> (String, HashSet<String>, HashSet
|
||||
Some(res)
|
||||
})
|
||||
.flat_map(|v| v.into_iter())
|
||||
// Ignore headings, images, and tables if inline = true
|
||||
.scan(vec![], |state: &mut Vec<Tag>, evt| {
|
||||
if inline {
|
||||
let new_evt = match evt {
|
||||
Event::Start(t) => {
|
||||
let tag = to_inline(t);
|
||||
state.push(tag.clone());
|
||||
Event::Start(tag)
|
||||
}
|
||||
Event::End(t) => match state.pop() {
|
||||
Some(other) => Event::End(other),
|
||||
None => Event::End(t),
|
||||
},
|
||||
e => e,
|
||||
};
|
||||
Some(new_evt)
|
||||
} else {
|
||||
Some(evt)
|
||||
}
|
||||
})
|
||||
.map(|evt| match evt {
|
||||
Event::Text(txt) => {
|
||||
let (evts, _, _, _, new_mentions, new_hashtags) = txt.chars().fold(
|
||||
@@ -239,7 +273,7 @@ mod tests {
|
||||
|
||||
for (md, mentions) in tests {
|
||||
assert_eq!(
|
||||
md_to_html(md, "").1,
|
||||
md_to_html(md, "", false).1,
|
||||
mentions
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
@@ -264,7 +298,7 @@ mod tests {
|
||||
|
||||
for (md, mentions) in tests {
|
||||
assert_eq!(
|
||||
md_to_html(md, "").2,
|
||||
md_to_html(md, "", false).2,
|
||||
mentions
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
@@ -272,4 +306,16 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
assert_eq!(
|
||||
md_to_html("# Hello", "", false).0,
|
||||
String::from("<h1>Hello</h1>\n")
|
||||
);
|
||||
assert_eq!(
|
||||
md_to_html("# Hello", "", true).0,
|
||||
String::from("<p>Hello</p>\n")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user