-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
258 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use yaml_peg::Node; | ||
|
||
#[derive(Default)] | ||
pub(crate) struct Background { | ||
src: String, | ||
size: String, | ||
position: String, | ||
repeat: String, | ||
opacity: String, | ||
} | ||
|
||
impl Background { | ||
pub(crate) fn new(meta: &Node) -> Result<Self, u64> { | ||
if let Ok(n) = meta.get("background") { | ||
Ok(Self { | ||
src: n.get_default("src", "", Node::as_str)?.to_string(), | ||
size: n.get_default("size", "", Node::as_value)?.to_string(), | ||
position: n.get_default("position", "", Node::as_value)?.to_string(), | ||
repeat: n.get_default("repeat", "", Node::as_value)?.to_string(), | ||
opacity: n.get_default("opacity", "", Node::as_value)?.to_string(), | ||
}) | ||
} else { | ||
Ok(Self::default()) | ||
} | ||
} | ||
|
||
pub(crate) fn is_valid(&self) -> bool { | ||
!self.src.is_empty() | ||
} | ||
|
||
pub(crate) fn attr(&self) -> String { | ||
let mut doc = String::new(); | ||
for (attr, member) in [ | ||
("", &self.src), | ||
("-size", &self.size), | ||
("-position", &self.position), | ||
("-repeat", &self.repeat), | ||
("-opacity", &self.opacity), | ||
] { | ||
if !member.is_empty() { | ||
doc += &format!(" data-background{}=\"{}\"", attr, member); | ||
} | ||
} | ||
doc | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use super::Error; | ||
use std::collections::HashMap; | ||
use yaml_peg::Node; | ||
|
||
pub(crate) struct FragMap(HashMap<String, HashMap<usize, String>>); | ||
|
||
impl FragMap { | ||
pub(crate) fn new(slide: &Node, count: &mut usize) -> Result<Self, Error> { | ||
let mut frag_map = HashMap::new(); | ||
for h in slide.get_default("fragment", vec![], Node::as_array)? { | ||
for (k, v) in h.as_map()?.iter() { | ||
let k = k.as_str()?; | ||
let v = v.as_str()?; | ||
if !frag_map.contains_key(k) { | ||
frag_map.insert(k.to_string(), HashMap::new()); | ||
} | ||
frag_map.get_mut(k).unwrap().insert(*count, v.to_string()); | ||
} | ||
*count += 1; | ||
} | ||
Ok(Self(frag_map)) | ||
} | ||
|
||
pub(crate) fn fragment(&mut self, tag: &str, inner: &str) -> String { | ||
if inner.is_empty() { | ||
return "".to_string(); | ||
} | ||
let tag = tag.to_string(); | ||
let mut head = String::new(); | ||
let mut end = String::new(); | ||
if let Some(frag) = self.0.get(&tag) { | ||
for (index, frag) in frag { | ||
head += &format!( | ||
"<span class=\"fragment {}\" data-fragment-index=\"{}\">", | ||
frag, index | ||
); | ||
end += "</span>"; | ||
} | ||
} | ||
head + inner + &end | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use pulldown_cmark::{html::push_html, CodeBlockKind, Event, Options, Parser, Tag}; | ||
|
||
const MARKED: Options = Options::from_bits_truncate( | ||
Options::ENABLE_TABLES.bits() | ||
| Options::ENABLE_SMART_PUNCTUATION.bits() | ||
| Options::ENABLE_TASKLISTS.bits() | ||
| Options::ENABLE_STRIKETHROUGH.bits(), | ||
); | ||
|
||
fn marked(e: Event) -> Event { | ||
match e { | ||
// Support line number for code block | ||
Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(info))) => { | ||
let info = info.replace(' ', ""); | ||
let mut head = String::new(); | ||
if info.is_empty() { | ||
head += "<pre><code>" | ||
} else { | ||
let lang = info.split('[').next().unwrap(); | ||
let line = info | ||
.replace(lang, "") | ||
.replace(|s| (s == '[') | (s == ']'), ""); | ||
head += &format!("<pre><code class=\"language-{}\"", lang); | ||
if !line.is_empty() { | ||
head += &format!(" data-line-numbers=\"{}\"", line); | ||
} | ||
head += ">"; | ||
} | ||
Event::Html(head.into()) | ||
} | ||
_ => e, | ||
} | ||
} | ||
|
||
pub(in crate::loader) fn md2html(text: &str) -> String { | ||
if text.is_empty() { | ||
"".to_string() | ||
} else { | ||
let mut out = String::new(); | ||
push_html(&mut out, Parser::new_ext(text, MARKED).map(marked)); | ||
out | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
pub(crate) struct Error(pub &'static str, pub u64); | ||
|
||
impl From<u64> for Error { | ||
fn from(pos: u64) -> Self { | ||
Self("invalid value type", pos) | ||
} | ||
} | ||
|
||
impl From<(&'static str, u64)> for Error { | ||
fn from((v, pos): (&'static str, u64)) -> Self { | ||
Self(v, pos) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use super::{sized_block, Error}; | ||
use yaml_peg::Node; | ||
|
||
pub(crate) fn footer(meta: &Node) -> Result<String, Error> { | ||
let footer = match meta.get("footer") { | ||
Ok(n) => n, | ||
Err(_) => return Ok(String::new()), | ||
}; | ||
let src = footer.get_default("src", "", Node::as_str)?; | ||
let label = footer.get_default("label", "", Node::as_str)?; | ||
if src.is_empty() && label.is_empty() { | ||
return Ok(String::new()); | ||
} | ||
let mut doc = | ||
"<div id=\"hidden\" style=\"display: none\"><div id=\"footer\"><div id=\"footer-left\">\n" | ||
.to_string(); | ||
let link = footer.get_default("link", "", Node::as_str)?; | ||
if !link.is_empty() { | ||
doc += &format!("<a href=\"{}\">", link); | ||
} | ||
let (src, size) = sized_block(&footer)?; | ||
doc += &format!("<img{}{}/>", src, size); | ||
let label = footer.get_default("label", "", Node::as_str)?; | ||
if !label.is_empty() { | ||
doc += &format!("<span> {}</span>", label); | ||
} | ||
if !link.is_empty() { | ||
doc += "</a>"; | ||
} | ||
doc += "\n</div></div></div>"; | ||
Ok(doc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use super::Error; | ||
use yaml_peg::Node; | ||
|
||
fn lower_camelcase(doc: &str) -> String { | ||
let mut s = String::new(); | ||
let mut is_word = false; | ||
for c in doc.chars() { | ||
if " -_".contains(c) { | ||
is_word = true; | ||
continue; | ||
} | ||
s.push(if is_word { | ||
is_word = false; | ||
c.to_ascii_uppercase() | ||
} else { | ||
c | ||
}); | ||
} | ||
s | ||
} | ||
|
||
pub(crate) fn js_option(meta: &Node) -> Result<String, Error> { | ||
let meta = match meta.get("option") { | ||
Ok(n) => n, | ||
Err(_) => return Ok(String::new()), | ||
}; | ||
let mut doc = String::new(); | ||
for (k, v) in meta.as_map()? { | ||
doc += &lower_camelcase(k.as_str()?); | ||
doc += ": "; | ||
if let Ok(s) = v.as_str() { | ||
doc += &format!("\"{}\"", s); | ||
} else { | ||
doc += v.as_value()?; | ||
} | ||
doc += ", "; | ||
} | ||
Ok(doc) | ||
} |
Oops, something went wrong.