Implement log levels
This commit is contained in:
parent
2cdf68082a
commit
874cac2df1
25 changed files with 497 additions and 223 deletions
|
|
@ -1,7 +1,12 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
static FIRST_PARSE: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Arguments {
|
||||
pub hostname: String,
|
||||
|
|
@ -51,7 +56,10 @@ fn parse(defaults: &Arguments, args: &[String]) -> Arguments {
|
|||
} else if argument.eq("-g") || argument.eq("--graph") {
|
||||
out_args.graph_path = PathBuf::from(parameter);
|
||||
} else {
|
||||
log!("Dropped unrecognized argument {argument}");
|
||||
if FIRST_PARSE.load(Ordering::SeqCst) {
|
||||
log!(WARN, "Dropped unrecognized argument {argument}");
|
||||
FIRST_PARSE.store(false, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Argument {arg:?} has no corresponding value")
|
||||
|
|
|
|||
|
|
@ -21,13 +21,17 @@ const LEXMAP: LexMap = &[
|
|||
];
|
||||
|
||||
fn lex(text: &str, map: LexMap, graph: &Graph, blocking: bool) -> TokenOutput {
|
||||
let mut instant = now();
|
||||
let mut tokens: Vec<Token> = Vec::default();
|
||||
let mut state = State::default();
|
||||
|
||||
let segments = segment::segment(text);
|
||||
let segments_count = segments.len();
|
||||
instant = tlog!(&instant, "Segmented {segments_count} segments");
|
||||
let lexemes = Lexeme::collect(&segments);
|
||||
instant = tlog!(&instant, "{segments_count} segments: Collected lexemes");
|
||||
|
||||
log!("Segments: {segments:?}");
|
||||
log!(VERBOSE, "Segments: {segments:?}");
|
||||
|
||||
let mut iterator = lexemes.iter().peekable();
|
||||
while let Some(lexeme) = iterator.next() {
|
||||
|
|
@ -67,14 +71,17 @@ fn lex(text: &str, map: LexMap, graph: &Graph, blocking: bool) -> TokenOutput {
|
|||
for (probe, lex) in map {
|
||||
if probe(lexeme) {
|
||||
let token = lex(lexeme);
|
||||
log!("Lexmap lexed {lexeme} into {token}");
|
||||
log!(VERBOSE, "Lexmap lexed {lexeme} into {token}");
|
||||
tokens.push(token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
instant = tlog!(&instant, "{segments_count} segments: Parsed");
|
||||
|
||||
context::close(&state, &mut tokens);
|
||||
tlog!(&instant, "{segments_count} segments: Closed");
|
||||
|
||||
TokenOutput {
|
||||
tokens,
|
||||
format_tokens: state.format_tokens,
|
||||
|
|
@ -107,7 +114,7 @@ pub fn format(input: &str, graph: &Graph) -> (String, Vec<Token>) {
|
|||
pub fn flatten(input: &str, graph: &Graph) -> String {
|
||||
let tokens = lex(input, LEXMAP, graph, true).tokens;
|
||||
let flat = tokens.iter().map(Token::flatten).collect::<String>();
|
||||
log!("Flattened {tokens:?} to {flat}");
|
||||
log!(VERBOSE, "Flattened {tokens:?} to {flat}");
|
||||
flat
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub fn parse(
|
|||
tokens: &mut Vec<Token>,
|
||||
graph: &Graph,
|
||||
) -> bool {
|
||||
log!("Solving: {}", state.clone().buffers.anchor);
|
||||
log!(VERBOSE, "Solving: {}", state.clone().buffers.anchor);
|
||||
let buffer = &mut state.buffers.anchor;
|
||||
let candidate = &mut buffer.candidate;
|
||||
|
||||
|
|
@ -25,16 +25,18 @@ pub fn parse(
|
|||
// would already have set its text to the word before the first pipe
|
||||
if candidate.text().is_empty() {
|
||||
log!(
|
||||
VERBOSE,
|
||||
"Seeking end of text at {:#?} -> {:#?}",
|
||||
lexeme.text(),
|
||||
lexeme.next()
|
||||
);
|
||||
if lexeme.next() == "|" {
|
||||
log!("End: Next lexeme is a pipe");
|
||||
log!(VERBOSE, "End: Next lexeme is a pipe");
|
||||
buffer.text.push_str(&lexeme.text());
|
||||
candidate.set_text(&buffer.text.clone());
|
||||
} else {
|
||||
log!(
|
||||
VERBOSE,
|
||||
"Pushing non-terminal {:#?} into buffer {:#?}",
|
||||
lexeme.text(),
|
||||
buffer.text
|
||||
|
|
@ -46,6 +48,7 @@ pub fn parse(
|
|||
|
||||
if candidate.destination().is_none() {
|
||||
log!(
|
||||
VERBOSE,
|
||||
"Seeking end of destination at {:#?} -> {:#?}",
|
||||
lexeme.text(),
|
||||
lexeme.next()
|
||||
|
|
@ -57,7 +60,7 @@ pub fn parse(
|
|||
&& lexeme.is_next_boundary()
|
||||
&& !lexeme.match_next_char('|')
|
||||
{
|
||||
log!("End: Plural anchor");
|
||||
log!(VERBOSE, "End: Plural anchor");
|
||||
candidate.set_destination(Some(&candidate.text().clone()));
|
||||
candidate.text_push("s");
|
||||
if lexeme.last() {
|
||||
|
|
@ -65,7 +68,7 @@ pub fn parse(
|
|||
}
|
||||
return true;
|
||||
} else if lexeme.match_char('|') && lexeme.is_next_delimiter() {
|
||||
log!("End: Pipe followed by delimiter");
|
||||
log!(VERBOSE, "End: Pipe followed by delimiter");
|
||||
if buffer.destination.is_empty() {
|
||||
if candidate.text().contains(':') {
|
||||
candidate.set_external(true);
|
||||
|
|
@ -76,29 +79,32 @@ pub fn parse(
|
|||
}
|
||||
return true;
|
||||
} else if lexeme.match_char('|') && !candidate.balanced() {
|
||||
log!("State: Found a pipe, but no boundary: destination follows");
|
||||
log!(
|
||||
VERBOSE,
|
||||
"State: Found a pipe, but no boundary: destination follows"
|
||||
);
|
||||
candidate.set_balanced(true);
|
||||
return true;
|
||||
} else if lexeme.match_char(':') {
|
||||
log!("State: Found a colon, marking anchor as external");
|
||||
log!(VERBOSE, "State: Found a colon, marking anchor as external");
|
||||
candidate.set_external(true);
|
||||
buffer.destination.push_str(&lexeme.text());
|
||||
return true;
|
||||
} else if lexeme.match_char('|') {
|
||||
log!("End: Explicit end-of-destination pipe");
|
||||
log!(VERBOSE, "End: Explicit end-of-destination pipe");
|
||||
candidate.set_destination(Some(&buffer.destination.clone()));
|
||||
return true;
|
||||
} else if !candidate.external() && lexeme.is_delimiter() {
|
||||
log!("End: Internal anchor trailed by delimiter");
|
||||
log!(VERBOSE, "End: Internal anchor trailed by delimiter");
|
||||
push(Some(&buffer.destination.clone()), tokens, state, graph);
|
||||
return false;
|
||||
} else if lexeme.is_next_whitespace() {
|
||||
log!("End: next is whitespace");
|
||||
log!(VERBOSE, "End: next is whitespace");
|
||||
buffer.destination.push_str(&lexeme.text());
|
||||
push(Some(&buffer.destination.clone()), tokens, state, graph);
|
||||
return true;
|
||||
} else if lexeme.last() {
|
||||
log!("End: end of input");
|
||||
log!(VERBOSE, "End: end of input");
|
||||
buffer.destination.push_str(&lexeme.text());
|
||||
push(Some(&buffer.destination.clone()), tokens, state, graph);
|
||||
return true;
|
||||
|
|
@ -107,6 +113,7 @@ pub fn parse(
|
|||
// pushing lexemes into the buffer until an end is found above
|
||||
} else {
|
||||
log!(
|
||||
VERBOSE,
|
||||
"Pushing non-terminal {:#?} into buffer {:#?}",
|
||||
lexeme.text(),
|
||||
buffer.destination,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub fn parse(
|
|||
match state.context.block {
|
||||
Block::None => {
|
||||
if PreFormat::probe(lexeme) {
|
||||
log!("Block Context: None -> PreFormat on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: None -> PreFormat on {lexeme}");
|
||||
state.context.block = Block::PreFormat;
|
||||
tokens.push(Token::PreFormat(PreFormat::new(true)));
|
||||
return true;
|
||||
|
|
@ -33,19 +33,19 @@ pub fn parse(
|
|||
iterator.peek().map_or(&Lexeme::default(), |l| l),
|
||||
&mut state.dom_ids,
|
||||
));
|
||||
log!("Block Context: None -> Header on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: None -> Header on {lexeme}");
|
||||
state.context.block = Block::Header(header.level());
|
||||
tokens.push(Token::Header(header));
|
||||
return true;
|
||||
} else if List::probe(lexeme) {
|
||||
log!("Block Context: None -> List on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: None -> List on {lexeme}");
|
||||
state.context.block = Block::List;
|
||||
state.buffers.list.candidate.ordered = lexeme.match_char('+');
|
||||
return super::list::parse(
|
||||
lexeme, state, tokens, iterator, graph,
|
||||
);
|
||||
} else if Paragraph::probe(lexeme) {
|
||||
log!("Block Context: None -> Paragraph on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: None -> Paragraph on {lexeme}");
|
||||
state.context.block = Block::Paragraph;
|
||||
tokens.push(Token::Paragraph(Paragraph::new(true)));
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ pub fn parse(
|
|||
Block::PreFormat => {
|
||||
if PreFormat::probe(lexeme) {
|
||||
tokens.push(Token::PreFormat(PreFormat::new(false)));
|
||||
log!("Block Context: PreFormat -> None on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: PreFormat -> None on {lexeme}");
|
||||
state.context.block = Block::None;
|
||||
} else {
|
||||
tokens.push(Token::Literal(Literal::lex(lexeme)));
|
||||
|
|
@ -63,14 +63,14 @@ pub fn parse(
|
|||
Block::Paragraph => {
|
||||
if Paragraph::probe_end(lexeme) {
|
||||
tokens.push(Token::Paragraph(Paragraph::new(false)));
|
||||
log!("Block Context: Paragraph -> None on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: Paragraph -> None on {lexeme}");
|
||||
state.context.block = Block::None;
|
||||
}
|
||||
},
|
||||
Block::Header(n) => {
|
||||
if lexeme.text() == "\n" {
|
||||
tokens.push(Token::Header(Header::from_u8(n, false, None)));
|
||||
log!("Block Context: Header -> None on {lexeme}");
|
||||
log!(VERBOSE, "Block Context: Header -> None on {lexeme}");
|
||||
state.context.block = Block::None;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ pub fn parse(
|
|||
match state.context.inline {
|
||||
Inline::None => {
|
||||
if Code::probe(lexeme) {
|
||||
log!("Inline Context: None -> Code on {lexeme}");
|
||||
log!(VERBOSE, "Inline Context: None -> Code on {lexeme}");
|
||||
state.context.inline = Inline::Code;
|
||||
tokens.push(Token::Code(Code::new(true)));
|
||||
return true;
|
||||
} else if Anchor::probe(lexeme) {
|
||||
log!("Inline Context: None -> Anchor on {lexeme}");
|
||||
log!(VERBOSE, "Inline Context: None -> Anchor on {lexeme}");
|
||||
state.context.inline = Inline::Anchor;
|
||||
state.buffers.anchor = AnchorBuffer::default();
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ pub fn parse(
|
|||
},
|
||||
Inline::Code => {
|
||||
if Code::probe(lexeme) {
|
||||
log!("Inline Context: Code -> None on {lexeme}");
|
||||
log!(VERBOSE, "Inline Context: Code -> None on {lexeme}");
|
||||
state.context.inline = Inline::None;
|
||||
tokens.push(Token::Code(Code::new(false)));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -55,14 +55,14 @@ pub fn parse(
|
|||
candidate.items.push(item_candidate.clone());
|
||||
}
|
||||
// push list candidate, reset state and exit context
|
||||
log!("Accepting list candidate {candidate}");
|
||||
log!(VERBOSE, "Accepting list candidate {candidate}");
|
||||
tokens.push(Token::List(candidate.clone()));
|
||||
state.context.block = Block::None;
|
||||
iterator.next();
|
||||
*buffer = state::ListBuffer::default();
|
||||
} else if lexeme.match_char('\n') {
|
||||
// found end of item, push it and reset state
|
||||
log!("Accepting item candidate {item_candidate}");
|
||||
log!(VERBOSE, "Accepting item candidate {item_candidate}");
|
||||
let (text, format_tokens) = format(&item_candidate.text, graph);
|
||||
item_candidate.text = text;
|
||||
state.format_tokens.extend_from_slice(&format_tokens);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::{prelude::*, syntax::content::parser::segment::delimiter::Delimiters};
|
||||
use crate::{syntax::content::parser::segment::delimiter::Delimiters};
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Lexeme {
|
||||
|
|
@ -27,9 +27,6 @@ impl Lexeme {
|
|||
}
|
||||
|
||||
pub fn next(&self) -> String {
|
||||
if self.next.is_empty() && !self.last {
|
||||
log!("Returning an empty string for next of non-last {self:?}");
|
||||
}
|
||||
self.next.clone()
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +236,7 @@ impl Lexeme {
|
|||
|
||||
impl fmt::Display for Lexeme {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use crate::dev::wrap;
|
||||
use crate::log::wrap;
|
||||
|
||||
let properties = if self.last && self.first {
|
||||
"[S] "
|
||||
|
|
|
|||
|
|
@ -24,30 +24,30 @@ pub fn parse(
|
|||
}
|
||||
|
||||
if Underline::probe(lexeme) {
|
||||
log!("Underline probed: {lexeme}");
|
||||
log!(VERBOSE, "Underline probed: {lexeme}");
|
||||
tokens
|
||||
.push(Token::Underline(Underline::new(!state.switches.underline)));
|
||||
state.switches.underline = !state.switches.underline;
|
||||
iterator.next();
|
||||
return true;
|
||||
} else if Oblique::probe(lexeme) {
|
||||
log!("Oblique probed: {lexeme}");
|
||||
log!(VERBOSE, "Oblique probed: {lexeme}");
|
||||
tokens.push(Token::Oblique(Oblique::new(!state.switches.oblique)));
|
||||
state.switches.oblique = !state.switches.oblique;
|
||||
return true;
|
||||
} else if Strike::probe(lexeme) {
|
||||
log!("Strike probed: {lexeme}");
|
||||
log!(VERBOSE, "Strike probed: {lexeme}");
|
||||
tokens.push(Token::Strike(Strike::new(!state.switches.crossout)));
|
||||
state.switches.crossout = !state.switches.crossout;
|
||||
iterator.next();
|
||||
return true;
|
||||
} else if Bold::probe(lexeme) {
|
||||
log!("Bold probed: {lexeme}");
|
||||
log!(VERBOSE, "Bold probed: {lexeme}");
|
||||
tokens.push(Token::Bold(Bold::new(!state.switches.bold)));
|
||||
state.switches.bold = !state.switches.bold;
|
||||
return true;
|
||||
} else if CheckBox::probe(lexeme) {
|
||||
log!("CheckBox probed: {lexeme}");
|
||||
log!(VERBOSE, "CheckBox probed: {lexeme}");
|
||||
tokens.push(Token::CheckBox(CheckBox::lex(lexeme)));
|
||||
iterator.next();
|
||||
iterator.next();
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ pub mod delimiter {
|
|||
atomized.push(c.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
atomized
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ impl Parseable for Anchor {
|
|||
|
||||
impl std::fmt::Display for Anchor {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
use crate::dev::wrap;
|
||||
use crate::log::wrap;
|
||||
|
||||
let wrapped_text = wrap(&self.text);
|
||||
let display_text = if wrapped_text.is_empty() {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl Parseable for CheckBox {
|
|||
|
||||
fn lex(lexeme: &Lexeme) -> CheckBox {
|
||||
use crate::prelude::*;
|
||||
log!("Lexing: {lexeme}");
|
||||
log!(VERBOSE, "Lexing: {lexeme}");
|
||||
if lexeme.match_next_char('x') {
|
||||
CheckBox::new(true)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ impl From<usize> for Level {
|
|||
let u8 = match u8::try_from(z) {
|
||||
Ok(u) => u,
|
||||
Err(e) => {
|
||||
log!("Truncating header level {z} to 6: {e:?}");
|
||||
log!(INFO, "Truncating header level {z} to 6: {e:?}");
|
||||
6
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ impl Parseable for Literal {
|
|||
|
||||
impl std::fmt::Display for Literal {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Literal {}", crate::dev::wrap(&self.text))
|
||||
write!(f, "Literal {}", crate::log::wrap(&self.text))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue