mirror of
https://github.com/TxtDot/dalet-rs.git
synced 2024-11-22 00:36:21 +03:00
feat: format cli command, fix format trim
This commit is contained in:
parent
68cd970a1f
commit
6338097658
6 changed files with 114 additions and 60 deletions
|
@ -40,13 +40,15 @@ This is element
|
||||||
br
|
br
|
||||||
|
|
||||||
# if no tag is specified but a '{- text}' is present, then the 'p' tag is placed
|
# if no tag is specified but a '{- text}' is present, then the 'p' tag is placed
|
||||||
# '\n' is deleted in this format. If a break line is needed in a paragraph, use ' \n'.
|
# '\n' is replaced with ' ' in this format.
|
||||||
{-
|
{-
|
||||||
Check Dalet too
|
Check Dalet too
|
||||||
This is one paragraph
|
This is one paragraph
|
||||||
}
|
}
|
||||||
|
|
||||||
{- This is another paragraph ({- text\}) }
|
{-
|
||||||
|
This is another paragraph ({- text\})
|
||||||
|
}
|
||||||
|
|
||||||
row "center" [
|
row "center" [
|
||||||
link "https://github.com/txtdot/txtdot": Homepage
|
link "https://github.com/txtdot/txtdot": Homepage
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[command(name = "cimengine", bin_name = "cimengine")]
|
#[command(name = "dalet", bin_name = "dalet")]
|
||||||
#[command(about = "CIMEngine build tools")]
|
#[command(about = "dalet cli")]
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub cmd: Commands,
|
pub cmd: Commands,
|
||||||
|
@ -10,4 +12,7 @@ pub struct Cli {
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
#[clap(author, version, about)]
|
#[clap(author, version, about)]
|
||||||
pub enum Commands {}
|
pub enum Commands {
|
||||||
|
/// Format file
|
||||||
|
Format { path: PathBuf },
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
lexer::types::{Spanned, Token},
|
lexer::types::{Spanned, Token},
|
||||||
utils::set_indent,
|
utils::{prepend_indent, set_indent},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn additional_str<'src>(
|
fn additional_str<'src>(
|
||||||
|
@ -83,72 +83,72 @@ pub fn format<'src>(spanned_tokens: &Vec<Spanned<Token<'src>>>) -> String {
|
||||||
}
|
}
|
||||||
Token::RSquare => {
|
Token::RSquare => {
|
||||||
current_indent -= 1;
|
current_indent -= 1;
|
||||||
format!("{}\n", set_indent("]", current_indent))
|
format!("{}\n", prepend_indent("]", current_indent))
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::NumberArgument(n) => format!("{n}"),
|
Token::NumberArgument(n) => format!("{n}"),
|
||||||
Token::TextArgument(t) => format!(" \"{t}\""),
|
Token::TextArgument(t) => format!(" \"{t}\""),
|
||||||
Token::TextBody(t) => format!(": {}\n", t.trim()),
|
Token::TextBody(t) => format!(": {}\n", t),
|
||||||
Token::MLText(t) => format!(
|
Token::MLText(t) => format!(
|
||||||
" {{\n{}\n{}\n",
|
" {{\n{}\n{}\n",
|
||||||
set_indent(t, current_indent + 1),
|
set_indent(t, current_indent + 1),
|
||||||
set_indent("}", current_indent)
|
prepend_indent("}", current_indent)
|
||||||
),
|
),
|
||||||
Token::MLMSText(n, t) => format!(
|
Token::MLMSText(n, t) => format!(
|
||||||
" {{~{n}\n{}\n{}\n",
|
" {{~{n}\n{}\n{}\n",
|
||||||
set_indent(t, current_indent + 1),
|
set_indent(t, current_indent + 1),
|
||||||
set_indent("}", current_indent)
|
prepend_indent("}", current_indent)
|
||||||
),
|
),
|
||||||
Token::RMLText(t) => format!(" {{#{t}}}\n"),
|
Token::RMLText(t) => format!(" {{#{t}}}\n"),
|
||||||
Token::Comment(c) => format!("{}\n", set_indent(&format!("#{c}"), current_indent)),
|
Token::Comment(c) => format!("{}\n", prepend_indent(&format!("#{c}"), current_indent)),
|
||||||
|
|
||||||
Token::TextTag(t) => format!("{}\n", set_indent(t, current_indent)),
|
Token::TextTag(t) => format!("{}\n", prepend_indent(t, current_indent)),
|
||||||
|
|
||||||
Token::El => set_indent("el", current_indent),
|
Token::El => prepend_indent("el", current_indent),
|
||||||
Token::H => set_indent("h", current_indent),
|
Token::H => prepend_indent("h", current_indent),
|
||||||
Token::P => set_indent("p", current_indent),
|
Token::P => prepend_indent("p", current_indent),
|
||||||
Token::Br => set_indent("br", current_indent),
|
Token::Br => prepend_indent("br", current_indent),
|
||||||
Token::Ul => set_indent("ul", current_indent),
|
Token::Ul => prepend_indent("ul", current_indent),
|
||||||
Token::Ol => set_indent("ol", current_indent),
|
Token::Ol => prepend_indent("ol", current_indent),
|
||||||
Token::Row => set_indent("row", current_indent),
|
Token::Row => prepend_indent("row", current_indent),
|
||||||
Token::Link => set_indent("link", current_indent),
|
Token::Link => prepend_indent("link", current_indent),
|
||||||
Token::Navlink => set_indent("navlink", current_indent),
|
Token::Navlink => prepend_indent("navlink", current_indent),
|
||||||
Token::Btn => set_indent("btn", current_indent),
|
Token::Btn => prepend_indent("btn", current_indent),
|
||||||
Token::Navbtn => set_indent("navbtn", current_indent),
|
Token::Navbtn => prepend_indent("navbtn", current_indent),
|
||||||
Token::Img => set_indent("img", current_indent),
|
Token::Img => prepend_indent("img", current_indent),
|
||||||
Token::Table => set_indent("table", current_indent),
|
Token::Table => prepend_indent("table", current_indent),
|
||||||
Token::Tcol => set_indent("tcol", current_indent),
|
Token::Tcol => prepend_indent("tcol", current_indent),
|
||||||
Token::Tpcol => set_indent("tpcol", current_indent),
|
Token::Tpcol => prepend_indent("tpcol", current_indent),
|
||||||
Token::Hr => set_indent("hr", current_indent),
|
Token::Hr => prepend_indent("hr", current_indent),
|
||||||
Token::B => set_indent("b", current_indent),
|
Token::B => prepend_indent("b", current_indent),
|
||||||
Token::I => set_indent("i", current_indent),
|
Token::I => prepend_indent("i", current_indent),
|
||||||
Token::Bq => set_indent("bq", current_indent),
|
Token::Bq => prepend_indent("bq", current_indent),
|
||||||
Token::Footlnk => set_indent("footlnk", current_indent),
|
Token::Footlnk => prepend_indent("footlnk", current_indent),
|
||||||
Token::Footn => set_indent("footn", current_indent),
|
Token::Footn => prepend_indent("footn", current_indent),
|
||||||
Token::A => set_indent("a", current_indent),
|
Token::A => prepend_indent("a", current_indent),
|
||||||
Token::S => set_indent("s", current_indent),
|
Token::S => prepend_indent("s", current_indent),
|
||||||
Token::Sup => set_indent("sup", current_indent),
|
Token::Sup => prepend_indent("sup", current_indent),
|
||||||
Token::Sub => set_indent("sub", current_indent),
|
Token::Sub => prepend_indent("sub", current_indent),
|
||||||
Token::Disc => set_indent("disc", current_indent),
|
Token::Disc => prepend_indent("disc", current_indent),
|
||||||
Token::Block => set_indent("block", current_indent),
|
Token::Block => prepend_indent("block", current_indent),
|
||||||
Token::Carousel => set_indent("carousel", current_indent),
|
Token::Carousel => prepend_indent("carousel", current_indent),
|
||||||
Token::Code => set_indent("code", current_indent),
|
Token::Code => prepend_indent("code", current_indent),
|
||||||
Token::Pre => set_indent("pre", current_indent),
|
Token::Pre => prepend_indent("pre", current_indent),
|
||||||
Token::Meta => set_indent("meta", current_indent),
|
Token::Meta => prepend_indent("meta", current_indent),
|
||||||
|
|
||||||
Token::ElOpen => {
|
Token::ElOpen => {
|
||||||
let s = set_indent("[[", current_indent);
|
let s = prepend_indent("[[", current_indent);
|
||||||
current_indent += 1;
|
current_indent += 1;
|
||||||
format!("{s}\n")
|
format!("{s}\n")
|
||||||
}
|
}
|
||||||
Token::ElClose => {
|
Token::ElClose => {
|
||||||
current_indent -= 1;
|
current_indent -= 1;
|
||||||
format!("{}\n", set_indent("]]", current_indent))
|
format!("{}\n", prepend_indent("]]", current_indent))
|
||||||
}
|
}
|
||||||
Token::Paragraph(t) => format!(
|
Token::Paragraph(t) => format!(
|
||||||
"{{-\n{}\n{}\n",
|
"{{-\n{}\n{}\n",
|
||||||
set_indent(t, current_indent + 1),
|
set_indent(t, current_indent + 1),
|
||||||
set_indent("}", current_indent)
|
prepend_indent("}", current_indent)
|
||||||
),
|
),
|
||||||
|
|
||||||
Token::EmptyLine => "\n".to_owned(),
|
Token::EmptyLine => "\n".to_owned(),
|
||||||
|
|
|
@ -75,7 +75,10 @@ pub fn lexer<'src>(
|
||||||
.ignore_then(just('}'))
|
.ignore_then(just('}'))
|
||||||
.labelled("Multi-line escape sequence");
|
.labelled("Multi-line escape sequence");
|
||||||
|
|
||||||
let text = none_of("\n").repeated().to_slice();
|
let text = none_of("\n")
|
||||||
|
.repeated()
|
||||||
|
.to_slice()
|
||||||
|
.padded_by(text::inline_whitespace());
|
||||||
|
|
||||||
let text_body = just(':')
|
let text_body = just(':')
|
||||||
.ignore_then(text)
|
.ignore_then(text)
|
||||||
|
@ -90,18 +93,17 @@ pub fn lexer<'src>(
|
||||||
let multiline_text_body = none_of("}\\")
|
let multiline_text_body = none_of("}\\")
|
||||||
.or(escape)
|
.or(escape)
|
||||||
.repeated()
|
.repeated()
|
||||||
|
.to_slice()
|
||||||
.labelled("Body of multiline text");
|
.labelled("Body of multiline text");
|
||||||
|
|
||||||
let paragraph = multiline_text_body
|
let paragraph = multiline_text_body
|
||||||
.clone()
|
.clone()
|
||||||
.to_slice()
|
|
||||||
.delimited_by(just("{-"), just("}"))
|
.delimited_by(just("{-"), just("}"))
|
||||||
.map(Token::Paragraph)
|
.map(Token::Paragraph)
|
||||||
.labelled("Paragraph syntax");
|
.labelled("Paragraph syntax");
|
||||||
|
|
||||||
let mltext = multiline_text_body
|
let mltext = multiline_text_body
|
||||||
.clone()
|
.clone()
|
||||||
.to_slice()
|
|
||||||
.delimited_by(just('{'), just('}'))
|
.delimited_by(just('{'), just('}'))
|
||||||
.map(Token::MLText)
|
.map(Token::MLText)
|
||||||
.labelled("Multiline text");
|
.labelled("Multiline text");
|
||||||
|
@ -112,14 +114,13 @@ pub fn lexer<'src>(
|
||||||
.labelled("Minimum spaces number");
|
.labelled("Minimum spaces number");
|
||||||
|
|
||||||
mlms_n
|
mlms_n
|
||||||
.then(multiline_text_body.clone().to_slice())
|
.then(multiline_text_body.clone())
|
||||||
.then_ignore(just("}"))
|
.then_ignore(just("}"))
|
||||||
.map(|(n, t)| Token::MLMSText(n, t))
|
.map(|(n, t)| Token::MLMSText(n, t))
|
||||||
.labelled("Multi line text with min spaces")
|
.labelled("Multi line text with min spaces")
|
||||||
};
|
};
|
||||||
|
|
||||||
let rmltext = multiline_text_body
|
let rmltext = multiline_text_body
|
||||||
.to_slice()
|
|
||||||
.delimited_by(just("{#"), just('}'))
|
.delimited_by(just("{#"), just('}'))
|
||||||
.map(Token::RMLText)
|
.map(Token::RMLText)
|
||||||
.labelled("Raw multiline text");
|
.labelled("Raw multiline text");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pub fn trim_indent(input: &str) -> String {
|
pub fn trim_indent(input: &str) -> String {
|
||||||
let lines: Vec<&str> = input.lines().collect();
|
let lines: Vec<&str> = trim_unused(input).lines().collect();
|
||||||
|
|
||||||
// Find the minimum indentation of non-empty lines
|
// Find the minimum indentation of non-empty lines
|
||||||
let min_indent = lines
|
let min_indent = lines
|
||||||
|
@ -21,28 +21,36 @@ pub fn trim_indent(input: &str) -> String {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
trim_newline(&trimmed_lines.join("\n")).to_owned()
|
trimmed_lines.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_indent(input: &str, indent: usize) -> String {
|
pub fn set_indent(input: &str, indent: usize) -> String {
|
||||||
prepend_indent(&trim_indent(input), &" ".repeat(indent))
|
prepend_indent(&trim_indent(input), indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim_newline<'a>(s: &'a str) -> &'a str {
|
fn trim_unused<'a>(s: &'a str) -> &'a str {
|
||||||
let mut trim_start = 0;
|
let mut trim_start = 0;
|
||||||
|
let mut been_newlines = false;
|
||||||
|
|
||||||
for start_char in s.chars() {
|
for start_char in s.chars() {
|
||||||
if start_char != '\n' && start_char != '\r' {
|
if !been_newlines
|
||||||
break;
|
&& (char::is_whitespace(start_char) && start_char != '\n' && start_char != '\r')
|
||||||
}
|
{
|
||||||
|
|
||||||
trim_start += 1;
|
trim_start += 1;
|
||||||
|
continue;
|
||||||
|
} else if start_char != '\n' && start_char != '\r' {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
been_newlines = true;
|
||||||
|
trim_start += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&s[(trim_start)..].trim_end()
|
&s[(trim_start)..].trim_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepend_indent(input: &str, indent: &str) -> String {
|
pub fn prepend_indent(input: &str, indent: usize) -> String {
|
||||||
|
let indent = &" ".repeat(indent);
|
||||||
let lines: Vec<String> = input
|
let lines: Vec<String> = input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| format!("{}{}", indent, line))
|
.map(|line| format!("{}{}", indent, line))
|
||||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -1,3 +1,41 @@
|
||||||
mod commands;
|
mod commands;
|
||||||
|
|
||||||
fn main() {}
|
use ariadne::{Color, Label, Report, ReportKind, Source};
|
||||||
|
use chumsky::Parser;
|
||||||
|
use clap::Parser as ClapParser;
|
||||||
|
use commands::{Cli, Commands::*};
|
||||||
|
use dalet::daleth::{format::format, lexer::lexer};
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = Cli::parse();
|
||||||
|
|
||||||
|
match args.cmd {
|
||||||
|
// TODO: add parser check before format
|
||||||
|
Format { path } => {
|
||||||
|
let src_file = &path.to_string_lossy().to_string();
|
||||||
|
let src = fs::read_to_string(src_file).unwrap();
|
||||||
|
|
||||||
|
let parsed = lexer().parse(&src);
|
||||||
|
|
||||||
|
match parsed.into_result() {
|
||||||
|
Ok(t) => {
|
||||||
|
fs::write(path, format(&t)).unwrap();
|
||||||
|
}
|
||||||
|
Err(e) => e.into_iter().for_each(|e| {
|
||||||
|
Report::build(ReportKind::Error, src_file, e.span().start)
|
||||||
|
.with_code("Compiler")
|
||||||
|
.with_message(e.to_string().clone())
|
||||||
|
.with_label(
|
||||||
|
Label::new((src_file, e.span().into_range()))
|
||||||
|
.with_message(e.to_string())
|
||||||
|
.with_color(Color::Red),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
.print((src_file, Source::from(&src)))
|
||||||
|
.unwrap()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue