Skip to content

Commit

Permalink
Working on wrapping code
Browse files Browse the repository at this point in the history
  • Loading branch information
WGUNDERWOOD committed May 3, 2024
1 parent 3641827 commit 351dac9
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 36 deletions.
7 changes: 1 addition & 6 deletions src/comments.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#[derive(Debug)]
pub struct Comment {
// index where the comment starts
idx: usize,
// does the comment have a leading space
space: bool,
pub idx: usize,
}

pub fn find_comment(line: &str) -> Option<Comment> {
Expand All @@ -24,7 +22,6 @@ pub fn find_comment(line: &str) -> Option<Comment> {
if prev_c == '%' {
return Some(Comment {
idx: 0,
space: false,
});
}

Expand All @@ -40,12 +37,10 @@ pub fn find_comment(line: &str) -> Option<Comment> {
if prev_c == ' ' {
return Some(Comment {
idx: i,
space: true,
});
} else if prev_c != '\\' {
return Some(Comment {
idx: i,
space: false,
});
}
}
Expand Down
14 changes: 10 additions & 4 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ use crate::indent::*;
use crate::subs::*;
use crate::wrap::*;

const MAX_WRAP_TRY: u8 = 3;

pub fn format_file(file: &str, debug: bool) -> String {
let mut new_file = remove_extra_newlines(file);
new_file = begin_end_environments_new_line(&new_file);
new_file = remove_tabs(&new_file);
new_file = remove_trailing_spaces(&new_file);
new_file = apply_indent(&new_file, debug);
//if needs_wrap(&file){
//new_file = wrap(&new_file);
//new_file = apply_indent(&new_file, debug);
//};

let mut wrap_tries = 0;
while needs_wrap(&file) && wrap_tries < MAX_WRAP_TRY {
wrap_tries += 1;
new_file = wrap(&new_file);
new_file = apply_indent(&new_file, debug);
};

new_file
}
3 changes: 3 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ mod tests {

#[test]
fn test_files() {
test_file("wrap", "tex");
/*
let filenames: Vec<String> = fs::read_dir("tests/")
.unwrap()
.map(|f| f.unwrap().file_name().into_string().unwrap())
Expand All @@ -69,5 +71,6 @@ mod tests {
let extension = &extensions[i];
test_file(&filename, &extension);
}
*/
}
}
100 changes: 83 additions & 17 deletions src/wrap.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,96 @@
// wrapping
use crate::comments::*;

const WRAP: usize = 80;

// any line under WRAP chars must be unchanged

// while line is long
// find the first break space (should be after non-space character)
// if break is after WRAP, throw warning
// if no comment, replace space with newline
// if comment and break before comment, replace space with newline
// if comment and break after comment
// if spaced comment
// replace space before comment with newline
// if non-spaced comment
// replace comment % with %\n%

pub fn needs_wrap(file: &str) -> bool {
file.lines().any(|l| l.len() > WRAP)
}

pub fn line_needs_wrap(line: &str) -> bool {
line.len() > WRAP
}

pub fn find_wrap_point(line: &str) -> Option<usize> {
let mut wrap_point: Option<usize> = None;
for i in 0..WRAP {
if line.chars().nth(i) == Some(' ') {
wrap_point = Some(i);
}
}
wrap_point
}

pub fn wrap_line(line: &str) -> String {
let mut remaining_line = line.to_string();
let mut new_line = "".to_string();
let mut can_wrap = true;
while line_needs_wrap(&remaining_line) && can_wrap {
let wrap_point = find_wrap_point(&remaining_line);
let comm = find_comment(&remaining_line);
match wrap_point {
Some(p) => {
let line_start = match comm {
Some(ref c) => {
if p > c.idx {
"%"
}
else {
""
}
}
None => ""
};
new_line.push_str(&remaining_line[0..p]);
new_line.push('\n');
remaining_line = remaining_line[p..remaining_line.len()].to_string();
remaining_line.insert_str(0, line_start);
},
None => {
can_wrap = false;
println!("long line cannot be wrapped!");
println!("{}", line);
}
}
}
new_line.push_str(&remaining_line);
new_line
}

pub fn wrap(file: &str) -> String {
let mut new_file = "".to_string();
let lines: Vec<&str> = file.lines().collect();
for line in lines.iter() {
for line in lines {
if line_needs_wrap(line) {
let new_line = wrap_line(line);
new_file.push_str(&new_line);
} else {
new_file.push_str(line);
}
new_file.push('\n');
}
new_file
}

#[cfg(test)]

//dbg!(&file);
file.to_string()
#[test]
fn test_wrap_line() {
// no comment
let s_in = "This line is too long because it has more than eighty characters inside it. \
Therefore it should be split.";
let s_out = "This line is too long because it has more than eighty characters inside it.\n \
Therefore it should be split.";
assert_eq!(wrap_line(s_in), s_out);
// break before comment
let s_in = "This line is too long because it has more than eighty characters inside it. \
Therefore it % should be split.";
let s_out = "This line is too long because it has more than eighty characters inside it.\n \
Therefore it % should be split.";
assert_eq!(wrap_line(s_in), s_out);
// break after comment
let s_in = "This line is too long because % it has more than eighty characters inside it. \
Therefore it should be split.";
let s_out = "This line is too long because % it has more than eighty characters inside it.\n\
% Therefore it should be split.";
assert_eq!(wrap_line(s_in), s_out);
}
2 changes: 1 addition & 1 deletion tests/wrap_in.tex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
This line is too long because it has more than% eighty characters inside it. Therefore it should be split.

% unbreakable line
Thislineistoolongbecauseithasmorethan%eightycharactersinsideit.Thereforeitshouldbesplit.
Thislineistoolongbecauseithasmorethan%eightycharactersinsideit.Buttherearenospacessoitcannotbesplit.

% long line only after indenting
(
Expand Down
16 changes: 8 additions & 8 deletions tests/wrap_out.tex
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
Therefore it % should be split.

% break after spaced comment
This line is too long because it has more than
% eighty characters inside it. Therefore it should be split.
This line is too long because it has more than % eighty characters inside it.
% Therefore it should be split.

% break after non-spaced comment
This line is too long because it has more than%
% eighty characters inside it. Therefore it should be split.
This line is too long because it has more than% eighty characters inside it.
% Therefore it should be split.

% unbreakable line
Thislineistoolongbecauseithasmorethan%eightycharactersinsideitThereforeitcannotbesplit.
Thislineistoolongbecauseithasmorethan%eightycharactersinsideit.Buttherearenospacessoitcannotbesplit.

% long line only after indenting
(
Expand All @@ -24,9 +24,9 @@
)

% double break after comment
This line has a long comment.
% This comment is very long so needs to be split over three lines which is
% another edge case which should be checked here with all these extra words
This line has a long comment. % This comment is very long so needs to be split
% over three lines which is another edge case which should be checked here with
% all these extra words

% double break after only comment
% This line is all a long comment. This comment is very long so needs to be
Expand Down

0 comments on commit 351dac9

Please sign in to comment.