Add custom stylesheet imports

feature/epub-rendering
trivernis 4 years ago
parent 1af43f4ff0
commit 8715ca7b41

2
Cargo.lock generated

@ -594,7 +594,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "snekdown" name = "snekdown"
version = "0.19.4" version = "0.20.0"
dependencies = [ dependencies = [
"asciimath-rs 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "asciimath-rs 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"charred 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "charred 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",

@ -1,6 +1,6 @@
[package] [package]
name = "snekdown" name = "snekdown"
version = "0.19.4" version = "0.20.0"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"

@ -219,5 +219,5 @@ The end goal is to have a markup language with features similar to LaTeX.
- [ ] Figures - [ ] Figures
- [ ] EPUB Rendering (PDF is too hard) - [ ] EPUB Rendering (PDF is too hard)
- [ ] Custom Elements via templates (50%) - [ ] Custom Elements via templates (50%)
- [ ] Custom Stylesheets - [x] Custom Stylesheets
- [ ] Smart arrows - [ ] Smart arrows

@ -45,6 +45,7 @@ pub enum Block {
Quote(Quote), Quote(Quote),
Import(Import), Import(Import),
Placeholder(Arc<RwLock<Placeholder>>), Placeholder(Arc<RwLock<Placeholder>>),
Null,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -64,6 +65,7 @@ pub struct Document {
pub(crate) placeholders: Vec<Arc<RwLock<Placeholder>>>, pub(crate) placeholders: Vec<Arc<RwLock<Placeholder>>>,
pub config: Configuration, pub config: Configuration,
pub bibliography: Bibliography, pub bibliography: Bibliography,
pub stylesheets: Vec<String>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -275,6 +277,7 @@ impl Document {
placeholders: Vec::new(), placeholders: Vec::new(),
config: Configuration::default(), config: Configuration::default(),
bibliography: Bibliography::new(), bibliography: Bibliography::new(),
stylesheets: Vec::new(),
} }
} }

@ -83,6 +83,7 @@ impl ToHtml for Block {
Block::Import(import) => import.to_html(), Block::Import(import) => import.to_html(),
Block::Placeholder(placeholder) => placeholder.read().unwrap().to_html(), Block::Placeholder(placeholder) => placeholder.read().unwrap().to_html(),
Block::MathBlock(m) => m.to_html(), Block::MathBlock(m) => m.to_html(),
Block::Null => "".to_string(),
} }
} }
} }
@ -119,12 +120,13 @@ impl ToHtml for Document {
<head {}>\ <head {}>\
<script id='MathJax-script' async src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'></script> <script id='MathJax-script' async src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'></script>
<style>{}</style>\ <style>{}</style>\
{}\
</head>\ </head>\
<body>\ <body>\
<div class='content'>{}</div>\ <div class='content'>{}</div>\
</body>\ </body>\
</html>", </html>",
path, style, inner path, style, self.stylesheets.iter().fold("".to_string(), |a, b| format!("{}<style>{}</style>", a, encode_minimal(b))), inner
) )
} else { } else {
format!( format!(

@ -5,6 +5,7 @@ use crate::elements::{
}; };
use crate::parser::inline::ParseInline; use crate::parser::inline::ParseInline;
use crate::parser::line::ParseLine; use crate::parser::line::ParseLine;
use crate::parser::ImportType;
use crate::Parser; use crate::Parser;
pub(crate) trait ParseBlock { pub(crate) trait ParseBlock {
@ -16,7 +17,7 @@ pub(crate) trait ParseBlock {
fn parse_paragraph(&mut self) -> ParseResult<Paragraph>; fn parse_paragraph(&mut self) -> ParseResult<Paragraph>;
fn parse_list(&mut self) -> ParseResult<List>; fn parse_list(&mut self) -> ParseResult<List>;
fn parse_table(&mut self) -> ParseResult<Table>; fn parse_table(&mut self) -> ParseResult<Table>;
fn parse_import(&mut self) -> ParseResult<Import>; fn parse_import(&mut self) -> ParseResult<Option<Import>>;
} }
impl ParseBlock for Parser { impl ParseBlock for Parser {
@ -44,7 +45,11 @@ impl ParseBlock for Parser {
} else if let Ok(quote) = self.parse_quote() { } else if let Ok(quote) = self.parse_quote() {
Block::Quote(quote) Block::Quote(quote)
} else if let Ok(import) = self.parse_import() { } else if let Ok(import) = self.parse_import() {
Block::Import(import) if let Some(import) = import {
Block::Import(import)
} else {
Block::Null
}
} else if let Some(_) = self.section_return { } else if let Some(_) = self.section_return {
return Err(self.ctm.err()); return Err(self.ctm.err());
} else if let Ok(pholder) = self.parse_placeholder() { } else if let Ok(pholder) = self.parse_placeholder() {
@ -294,7 +299,7 @@ impl ParseBlock for Parser {
} }
/// parses an import and starts a new task to parse the document of the import /// parses an import and starts a new task to parse the document of the import
fn parse_import(&mut self) -> ParseResult<Import> { fn parse_import(&mut self) -> ParseResult<Option<Import>> {
let start_index = self.ctm.get_index(); let start_index = self.ctm.get_index();
self.ctm.seek_whitespace(); self.ctm.seek_whitespace();
self.ctm self.ctm
@ -321,10 +326,13 @@ impl ParseBlock for Parser {
self.ctm.seek_whitespace(); self.ctm.seek_whitespace();
if let Ok(anchor) = self.import_document(path.clone()) { match self.import(path.clone()) {
Ok(Import { path, anchor }) ImportType::Document(Ok(anchor)) => Ok(Some(Import { path, anchor })),
} else { ImportType::Stylesheet(Ok(content)) => {
Err(self.ctm.err()) self.document.stylesheets.push(content);
Ok(None)
}
_ => Err(self.ctm.err()),
} }
} }
} }

@ -8,7 +8,7 @@ use crate::references::configuration::Configuration;
use charred::tapemachine::{CharTapeMachine, TapeError, TapeResult}; use charred::tapemachine::{CharTapeMachine, TapeError, TapeResult};
use colored::*; use colored::*;
use crossbeam_utils::sync::WaitGroup; use crossbeam_utils::sync::WaitGroup;
use std::fs::File; use std::fs::{read_to_string, File};
use std::io; use std::io;
use std::io::{BufRead, BufReader, Cursor}; use std::io::{BufRead, BufReader, Cursor};
use std::path::PathBuf; use std::path::PathBuf;
@ -142,8 +142,7 @@ impl Parser {
} }
/// starts up a new thread to parse the imported document /// starts up a new thread to parse the imported document
fn import_document(&mut self, path: String) -> ParseResult<Arc<RwLock<ImportAnchor>>> { fn import_document(&mut self, path: PathBuf) -> ParseResult<Arc<RwLock<ImportAnchor>>> {
let path = self.transform_path(path);
if !path.exists() || !path.is_file() { if !path.exists() || !path.is_file() {
println!( println!(
"{}", "{}",
@ -189,6 +188,20 @@ impl Parser {
Ok(anchor) Ok(anchor)
} }
fn import(&mut self, path: String) -> ImportType {
let path = self.transform_path(path);
match path.extension() {
Some(e) if e.to_str().unwrap() == "css" => {
if let Ok(content) = read_to_string(path) {
ImportType::Stylesheet(Ok(content))
} else {
ImportType::Stylesheet(Err(ParseError::new(self.ctm.get_index())))
}
}
_ => ImportType::Document(self.import_document(path)),
}
}
/// parses the given text into a document /// parses the given text into a document
pub fn parse(&mut self) -> Document { pub fn parse(&mut self) -> Document {
self.document.path = if let Some(path) = &self.path { self.document.path = if let Some(path) = &self.path {
@ -220,3 +233,8 @@ impl Parser {
document document
} }
} }
pub(crate) enum ImportType {
Document(ParseResult<Arc<RwLock<ImportAnchor>>>),
Stylesheet(ParseResult<String>),
}

Loading…
Cancel
Save