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]]
name = "snekdown"
version = "0.19.4"
version = "0.20.0"
dependencies = [
"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)",

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

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

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

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

@ -5,6 +5,7 @@ use crate::elements::{
};
use crate::parser::inline::ParseInline;
use crate::parser::line::ParseLine;
use crate::parser::ImportType;
use crate::Parser;
pub(crate) trait ParseBlock {
@ -16,7 +17,7 @@ pub(crate) trait ParseBlock {
fn parse_paragraph(&mut self) -> ParseResult<Paragraph>;
fn parse_list(&mut self) -> ParseResult<List>;
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 {
@ -44,7 +45,11 @@ impl ParseBlock for Parser {
} else if let Ok(quote) = self.parse_quote() {
Block::Quote(quote)
} else if let Ok(import) = self.parse_import() {
if let Some(import) = import {
Block::Import(import)
} else {
Block::Null
}
} else if let Some(_) = self.section_return {
return Err(self.ctm.err());
} 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
fn parse_import(&mut self) -> ParseResult<Import> {
fn parse_import(&mut self) -> ParseResult<Option<Import>> {
let start_index = self.ctm.get_index();
self.ctm.seek_whitespace();
self.ctm
@ -321,10 +326,13 @@ impl ParseBlock for Parser {
self.ctm.seek_whitespace();
if let Ok(anchor) = self.import_document(path.clone()) {
Ok(Import { path, anchor })
} else {
Err(self.ctm.err())
match self.import(path.clone()) {
ImportType::Document(Ok(anchor)) => Ok(Some(Import { path, anchor })),
ImportType::Stylesheet(Ok(content)) => {
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 colored::*;
use crossbeam_utils::sync::WaitGroup;
use std::fs::File;
use std::fs::{read_to_string, File};
use std::io;
use std::io::{BufRead, BufReader, Cursor};
use std::path::PathBuf;
@ -142,8 +142,7 @@ impl Parser {
}
/// starts up a new thread to parse the imported document
fn import_document(&mut self, path: String) -> ParseResult<Arc<RwLock<ImportAnchor>>> {
let path = self.transform_path(path);
fn import_document(&mut self, path: PathBuf) -> ParseResult<Arc<RwLock<ImportAnchor>>> {
if !path.exists() || !path.is_file() {
println!(
"{}",
@ -189,6 +188,20 @@ impl Parser {
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
pub fn parse(&mut self) -> Document {
self.document.path = if let Some(path) = &self.path {
@ -220,3 +233,8 @@ impl Parser {
document
}
}
pub(crate) enum ImportType {
Document(ParseResult<Arc<RwLock<ImportAnchor>>>),
Stylesheet(ParseResult<String>),
}

Loading…
Cancel
Save