Add to html implementation

pull/1/head
trivernis 5 years ago
parent ee9198d001
commit bc1d620aa0

@ -18,48 +18,43 @@ pub enum Inline {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Document { pub struct Document {
elements: Vec<Block>, pub(crate) elements: Vec<Block>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Section { pub struct Section {
header: Header, pub(crate) header: Header,
elements: Vec<Block>, pub(crate) elements: Vec<Block>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Header { pub struct Header {
pub size: u8, pub(crate) size: u8,
pub line: Inline, pub(crate) line: Inline,
}
#[derive(Clone, Debug)]
pub struct BlockQuote {
paragraph: Paragraph,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Paragraph { pub struct Paragraph {
pub elements: Vec<Inline>, pub(crate) elements: Vec<Inline>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct List { pub struct List {
pub ordered: bool, pub(crate) ordered: bool,
pub items: Vec<ListItem>, pub(crate) items: Vec<ListItem>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ListItem { pub struct ListItem {
text: Inline, pub(crate) text: Inline,
pub(crate) level: u16, pub(crate) level: u16,
pub(crate) children: Vec<ListItem>, pub(crate) children: Vec<ListItem>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Table { pub struct Table {
header: Row, pub(crate) header: Row,
pub rows: Vec<Row>, pub(crate) rows: Vec<Row>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -155,8 +150,8 @@ pub struct MonospaceText {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Url { pub struct Url {
description: Option<String>, pub description: Option<String>,
url: String, pub url: String,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

@ -0,0 +1,243 @@
use crate::elements::*;
pub trait ToHtml {
fn to_html(&self) -> String;
}
impl ToHtml for Inline {
fn to_html(&self) -> String {
match self {
Inline::Text(text) => text.to_html(),
}
}
}
impl ToHtml for SubText {
fn to_html(&self) -> String {
match self {
SubText::Url(url) => url.to_html(),
SubText::Monospace(mono) => mono.to_html(),
SubText::Striked(striked) => striked.to_html(),
SubText::Plain(plain) => plain.to_html(),
SubText::Italic(italic) => italic.to_html(),
SubText::Underlined(under) => under.to_html(),
SubText::Bold(bold) => bold.to_html(),
SubText::Image(img) => img.to_html(),
_ => "".to_string(),
}
}
}
impl ToHtml for Block {
fn to_html(&self) -> String {
match self {
Block::Paragraph(para) => para.to_html(),
Block::List(list) => list.to_html(),
Block::Table(table) => table.to_html(),
Block::CodeBlock(code) => code.to_html(),
Block::Quote(quote) => quote.to_html(),
Block::Section(section) => section.to_html(),
Block::Import(import) => import.to_html(),
}
}
}
impl ToHtml for Document {
fn to_html(&self) -> String {
let inner = self
.elements
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<html><body>{}</body></html>", inner)
}
}
impl ToHtml for Import {
fn to_html(&self) -> String {
let anchor = self.anchor.lock().unwrap();
if let Some(document) = &anchor.document {
document.to_html()
} else {
"".to_string()
}
}
}
impl ToHtml for Section {
fn to_html(&self) -> String {
let inner = self
.elements
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<section>{}{}</section>", self.header.to_html(), inner)
}
}
impl ToHtml for Header {
fn to_html(&self) -> String {
format!("<h{0}>{1}</h{0}>", self.size, self.line.to_html())
}
}
impl ToHtml for Paragraph {
fn to_html(&self) -> String {
let inner = self
.elements
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<p>{}</p>", inner)
}
}
impl ToHtml for List {
fn to_html(&self) -> String {
let inner = self
.items
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
if self.ordered {
format!("<ol>{}</ol>", inner)
} else {
format!("<ul>{}</ul>", inner)
}
}
}
impl ToHtml for ListItem {
fn to_html(&self) -> String {
let inner = self
.children
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<li>{}<ul>{}</ul></li>", self.text.to_html(), inner)
}
}
impl ToHtml for Table {
fn to_html(&self) -> String {
let head = self.header.cells.iter().fold("".to_string(), |a, b| {
format!("{}<th>{}</th>", a, b.text.to_html())
});
let body = self
.rows
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<table><tr>{}<tr>{}</table>", head, body)
}
}
impl ToHtml for Row {
fn to_html(&self) -> String {
let inner = self
.cells
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()));
format!("<tr>{}</tr>", inner)
}
}
impl ToHtml for Cell {
fn to_html(&self) -> String {
format!("<td>{}</td>", self.text.to_html())
}
}
impl ToHtml for CodeBlock {
fn to_html(&self) -> String {
format!(
"<div><code lang='{}'>{}</code></div>",
self.language.clone(),
self.code.clone()
)
}
}
impl ToHtml for Quote {
fn to_html(&self) -> String {
let text = self
.text
.iter()
.fold("".to_string(), |a, b| format!("{}<br>{}", a, b.to_html()));
if let Some(meta) = self.metadata.clone() {
format!(
"<div><blockquote>{}</blockquote><span>- {}</span></div>",
text, meta.data
)
} else {
format!("<blockquote>{}</blockquote>", text)
}
}
}
impl ToHtml for Text {
fn to_html(&self) -> String {
self.subtext
.iter()
.fold("".to_string(), |a, b| format!("{}{}", a, b.to_html()))
}
}
impl ToHtml for Image {
fn to_html(&self) -> String {
if let Some(description) = self.url.description.clone() {
format!(
"<div>\
<a href={0}>\
<img src='{0}' alt='{1}'/>\
</a>\
<label class='imageDescription'>{1}</label>
</div>",
self.url.url.clone(),
description
)
} else {
format!("<a href={0}><img src='{0}'/></a>", self.url.url.clone(),)
}
}
}
impl ToHtml for BoldText {
fn to_html(&self) -> String {
format!("<u>{}</u>", self.value.to_html())
}
}
impl ToHtml for UnderlinedText {
fn to_html(&self) -> String {
format!("<u>{}</u>", self.value.to_html())
}
}
impl ToHtml for ItalicText {
fn to_html(&self) -> String {
format!("<i>{}</i>", self.value.to_html())
}
}
impl ToHtml for StrikedText {
fn to_html(&self) -> String {
format!("<del>{}</del>", self.value.to_html())
}
}
impl ToHtml for MonospaceText {
fn to_html(&self) -> String {
format!("<code>{}</code>", self.value.to_html())
}
}
impl ToHtml for Url {
fn to_html(&self) -> String {
if let Some(description) = self.description.clone() {
format!("<a href='{}'>{}</a>", self.url.clone(), description)
} else {
format!("<a href='{}'>{}</a>", self.url.clone(), self.url.clone())
}
}
}
impl ToHtml for PlainText {
fn to_html(&self) -> String {
self.value.clone()
}
}

@ -0,0 +1 @@
pub mod html;

@ -1,3 +1,4 @@
pub mod elements; pub mod elements;
pub mod format;
pub mod parser; pub mod parser;
pub mod tokens; pub mod tokens;

@ -1,3 +1,4 @@
use markdown_rs::format::html::ToHtml;
use markdown_rs::parser::Parser; use markdown_rs::parser::Parser;
use std::fs::{read_to_string, write}; use std::fs::{read_to_string, write};
use std::time::Instant; use std::time::Instant;
@ -12,4 +13,5 @@ fn main() {
let document = parser.parse(); let document = parser.parse();
println!("Total duration: {:?}", start.elapsed()); println!("Total duration: {:?}", start.elapsed());
write("test/document.ast", format!("{:#?}", document)).unwrap(); write("test/document.ast", format!("{:#?}", document)).unwrap();
write("test/document.html", document.to_html()).unwrap()
} }

Loading…
Cancel
Save