Change whitespace behaviour

A single linebreak will be ignored in plain text while a double line
break will be converted to a single linebreak. All following
linebreaks are taken as-is and rendered as normal linebreaks.
(Fixes #13)

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/17/head
trivernis 4 years ago
parent 661a6e5a85
commit d5df0b6f05
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

6
Cargo.lock generated

@ -235,9 +235,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "charred" name = "charred"
version = "0.3.5" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed9759715d56a062d5636cd0cbc71f2aa8a978afe08c572a69e65e8cf53418f5" checksum = "4163b788273102d5de1aaf35a76b1c0e347844842f5278d4d738ad08170e0ea8"
[[package]] [[package]]
name = "chrono" name = "chrono"
@ -2315,7 +2315,7 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]] [[package]]
name = "snekdown" name = "snekdown"
version = "0.32.3" version = "0.33.0"
dependencies = [ dependencies = [
"asciimath-rs", "asciimath-rs",
"base64 0.12.3", "base64 0.12.3",

@ -1,6 +1,6 @@
[package] [package]
name = "snekdown" name = "snekdown"
version = "0.32.3" version = "0.33.0"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"
@ -21,7 +21,7 @@ path = "src/main.rs"
pdf = ["headless_chrome", "failure"] pdf = ["headless_chrome", "failure"]
[dependencies] [dependencies]
charred = "0.3.5" charred = "0.3.6"
asciimath-rs = "0.5.7" asciimath-rs = "0.5.7"
bibliographix = "0.6.0" bibliographix = "0.6.0"
crossbeam-utils = "0.7.2" crossbeam-utils = "0.7.2"

@ -251,7 +251,7 @@ impl ToHtml for Paragraph {
} }
if self.elements.len() > 1 { if self.elements.len() > 1 {
for element in &self.elements[1..] { for element in &self.elements[1..] {
writer.write("<br/>".to_string())?; writer.write(" ".to_string())?;
element.to_html(writer)?; element.to_html(writer)?;
} }
} }

@ -165,6 +165,7 @@ impl ParseBlock for Parser {
fn parse_quote(&mut self) -> ParseResult<Quote> { fn parse_quote(&mut self) -> ParseResult<Quote> {
let start_index = self.ctm.get_index(); let start_index = self.ctm.get_index();
self.ctm.seek_whitespace(); self.ctm.seek_whitespace();
let metadata = if let Ok(meta) = self.parse_inline_metadata() { let metadata = if let Ok(meta) = self.parse_inline_metadata() {
Some(meta) Some(meta)
} else { } else {
@ -199,11 +200,12 @@ impl ParseBlock for Parser {
/// Parses a paragraph /// Parses a paragraph
fn parse_paragraph(&mut self) -> ParseResult<Paragraph> { fn parse_paragraph(&mut self) -> ParseResult<Paragraph> {
self.ctm.seek_whitespace();
let mut paragraph = Paragraph::new(); let mut paragraph = Paragraph::new();
while let Ok(token) = self.parse_line() {
paragraph.add_element(token); while let Ok(element) = self.parse_line() {
paragraph.add_element(element);
let start_index = self.ctm.get_index(); let start_index = self.ctm.get_index();
if self.ctm.check_any_sequence(&BLOCK_SPECIAL_CHARS) if self.ctm.check_any_sequence(&BLOCK_SPECIAL_CHARS)
|| self.ctm.check_any(&self.block_break_at) || self.ctm.check_any(&self.block_break_at)
{ {

@ -1,7 +1,8 @@
use super::ParseResult; use super::ParseResult;
use crate::elements::tokens::*; use crate::elements::tokens::*;
use crate::elements::Inline::LineBreak;
use crate::elements::{BibEntry, Metadata}; use crate::elements::{BibEntry, Metadata};
use crate::elements::{Cell, Centered, Header, Inline, Line, ListItem, Row, Ruler, TextLine}; use crate::elements::{Cell, Centered, Header, Line, ListItem, Row, Ruler, TextLine};
use crate::parser::inline::ParseInline; use crate::parser::inline::ParseInline;
use crate::Parser; use crate::Parser;
use bibliographix::bibliography::bibliography_entry::BibliographyEntry; use bibliographix::bibliography::bibliography_entry::BibliographyEntry;
@ -16,6 +17,7 @@ pub(crate) trait ParseLine {
fn parse_row(&mut self) -> ParseResult<Row>; fn parse_row(&mut self) -> ParseResult<Row>;
fn parse_centered(&mut self) -> ParseResult<Centered>; fn parse_centered(&mut self) -> ParseResult<Centered>;
fn parse_ruler(&mut self) -> ParseResult<Ruler>; fn parse_ruler(&mut self) -> ParseResult<Ruler>;
fn parse_paragraph_break(&mut self) -> ParseResult<TextLine>;
fn parse_text_line(&mut self) -> ParseResult<TextLine>; fn parse_text_line(&mut self) -> ParseResult<TextLine>;
fn parse_bib_entry(&mut self) -> ParseResult<BibEntry>; fn parse_bib_entry(&mut self) -> ParseResult<BibEntry>;
} }
@ -36,6 +38,9 @@ impl ParseLine for Parser {
} else if let Ok(bib) = self.parse_bib_entry() { } else if let Ok(bib) = self.parse_bib_entry() {
log::trace!("Line::BibEntry"); log::trace!("Line::BibEntry");
Ok(Line::BibEntry(bib)) Ok(Line::BibEntry(bib))
} else if let Ok(text) = self.parse_paragraph_break() {
log::trace!("Line::LineBreak");
Ok(Line::Text(text))
} else if let Ok(text) = self.parse_text_line() { } else if let Ok(text) = self.parse_text_line() {
log::trace!("Line::Text"); log::trace!("Line::Text");
Ok(Line::Text(text)) Ok(Line::Text(text))
@ -166,6 +171,8 @@ impl ParseLine for Parser {
/// Parses a line of text /// Parses a line of text
fn parse_text_line(&mut self) -> ParseResult<TextLine> { fn parse_text_line(&mut self) -> ParseResult<TextLine> {
let mut text = TextLine::new(); let mut text = TextLine::new();
let start_index = self.ctm.get_index();
while let Ok(subtext) = self.parse_inline() { while let Ok(subtext) = self.parse_inline() {
text.add_subtext(subtext); text.add_subtext(subtext);
if self.ctm.check_eof() || self.ctm.check_any(&self.inline_break_at) { if self.ctm.check_eof() || self.ctm.check_any(&self.inline_break_at) {
@ -173,21 +180,36 @@ impl ParseLine for Parser {
} }
} }
// add a linebreak when encountering \n\n
if self.ctm.check_char(&LB) { if self.ctm.check_char(&LB) {
if let Ok(_) = self.ctm.seek_one() { self.ctm.try_seek();
if self.ctm.check_char(&LB) { if self.ctm.check_char(&LB) {
text.add_subtext(Inline::LineBreak) text.add_subtext(LineBreak);
}
self.ctm.try_seek();
} }
} }
if text.subtext.len() > 0 { if text.subtext.len() > 0 {
Ok(text) Ok(text)
} else { } else {
Err(self.ctm.err().into()) Err(self.ctm.rewind_with_error(start_index).into())
} }
} }
/// Parses a paragraph break
fn parse_paragraph_break(&mut self) -> ParseResult<TextLine> {
let start_index = self.ctm.get_index();
self.ctm.assert_char(&LB, Some(start_index))?;
self.ctm.seek_one()?;
let mut line = TextLine::new();
line.subtext.push(LineBreak);
Ok(line)
}
fn parse_bib_entry(&mut self) -> ParseResult<BibEntry> { fn parse_bib_entry(&mut self) -> ParseResult<BibEntry> {
let start_index = self.ctm.get_index(); let start_index = self.ctm.get_index();
self.ctm.seek_any(&INLINE_WHITESPACE)?; self.ctm.seek_any(&INLINE_WHITESPACE)?;
@ -239,6 +261,7 @@ impl ParseLine for Parser {
} }
} }
}; };
self.ctm.seek_whitespace();
self.options self.options
.document .document

@ -136,6 +136,11 @@ impl Parser {
/// Returns a string of the current position in the file /// Returns a string of the current position in the file
pub(crate) fn get_position_string(&self) -> String { pub(crate) fn get_position_string(&self) -> String {
let char_index = self.ctm.get_index(); let char_index = self.ctm.get_index();
self.get_position_string_for_index(char_index)
}
/// Returns a string of the given index position in the file
fn get_position_string_for_index(&self, char_index: usize) -> String {
let text = self.ctm.get_text(); let text = self.ctm.get_text();
let mut text_unil = text[..char_index].to_vec(); let mut text_unil = text[..char_index].to_vec();
let line_number = text_unil.iter().filter(|c| c == &&LB).count(); let line_number = text_unil.iter().filter(|c| c == &&LB).count();
@ -180,10 +185,10 @@ impl Parser {
let anchor = Arc::new(RwLock::new(ImportAnchor::new())); let anchor = Arc::new(RwLock::new(ImportAnchor::new()));
let anchor_clone = Arc::clone(&anchor); let anchor_clone = Arc::clone(&anchor);
let wg = self.wg.clone(); let wg = self.wg.clone();
let mut chid_parser = self.create_child(path.clone()); let mut child_parser = self.create_child(path.clone());
let _ = thread::spawn(move || { let _ = thread::spawn(move || {
let document = chid_parser.parse(); let document = child_parser.parse();
anchor_clone.write().unwrap().set_document(document); anchor_clone.write().unwrap().set_document(document);
drop(wg); drop(wg);
@ -332,7 +337,18 @@ impl Parser {
if self.ctm.check_eof() { if self.ctm.check_eof() {
break; break;
} }
eprintln!("{}", err); match err {
ParseError::TapeError(t) => {
log::error!(
"Parse Error: {}\n\t--> {}\n",
t,
self.get_position_string_for_index(t.get_index())
)
}
_ => {
log::error!("{}", err)
}
}
break; break;
} }
} }

Loading…
Cancel
Save