Skip to content

Commit

Permalink
Document everything
Browse files Browse the repository at this point in the history
  • Loading branch information
WGUNDERWOOD committed Sep 2, 2024
1 parent 6eeb5d0 commit d91cda1
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub struct State {
}

impl State {
/// Construct a new default state
pub const fn new() -> Self {
Self {
linum_old: 0,
Expand All @@ -94,6 +95,7 @@ impl State {
}
}

/// Ensure that the indentation returns to zero at the end of the file
fn indents_return_to_zero(text: &str) -> bool {
!text.lines().last().unwrap_or_default().starts_with(' ')
}
10 changes: 10 additions & 0 deletions src/ignore.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
//! Utilities for ignoring/skipping source lines
use crate::format::*;
use crate::logging::*;
use log::Level::Warn;

/// Information on the ignored state of a line
#[derive(Clone, Debug)]
pub struct Ignore {
/// Whether the line is in an ignore block
pub actual: bool,
/// Whether the line should be ignored/skipped
pub visual: bool,
}

impl Ignore {
/// Construct a new ignore state
pub const fn new() -> Self {
Self {
actual: false,
Expand All @@ -17,6 +23,7 @@ impl Ignore {
}
}

/// Determine whether a line should be ignored
pub fn get_ignore(
line: &str,
state: &State,
Expand Down Expand Up @@ -69,14 +76,17 @@ pub fn get_ignore(
Ignore { actual, visual }
}

/// Check if a line contains a skip directive
fn contains_ignore_skip(line: &str) -> bool {
line.ends_with("% tex-fmt: skip")
}

/// Check if a line contains the start of an ignore block
fn contains_ignore_begin(line: &str) -> bool {
line.ends_with("% tex-fmt: off")
}

/// Check if a line contains the end of an ignore block
fn contains_ignore_end(line: &str) -> bool {
line.ends_with("% tex-fmt: on")
}
15 changes: 12 additions & 3 deletions src/indent.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
//! Utilities for indenting source lines
use crate::comments::*;
use crate::format::*;
use crate::ignore::*;
use crate::logging::*;
use crate::parse::*;
use crate::regexes::*;
use crate::verbatim::*;
use crate::TAB;
use core::cmp::max;
use log::Level::{Trace, Warn};

/// Opening delimiters
const OPENS: [char; 3] = ['(', '[', '{'];
/// Closing delimiters
const CLOSES: [char; 3] = [')', ']', '}'];

/// Information on the indentation state of a line
#[derive(Debug, Clone)]
pub struct Indent {
/// The indentation level of a line
pub actual: i8,
/// The visual indentation level of a line
pub visual: i8,
}

impl Indent {
/// Construct a new indentation state
pub const fn new() -> Self {
Self {
actual: 0,
Expand All @@ -27,7 +34,7 @@ impl Indent {
}
}

// calculate total indentation change due to current line
/// Calculate total indentation change due to the current line
fn get_diff(line: &str) -> i8 {
// list environments get double indents
let mut diff: i8 = 0;
Expand Down Expand Up @@ -64,7 +71,7 @@ fn get_diff(line: &str) -> i8 {
diff
}

// calculate dedentation for current line compared to previous
/// Calculate dedentation for the current line
fn get_back(line: &str) -> i8 {
let mut back: i8 = 0;
let mut cumul: i8 = 0;
Expand Down Expand Up @@ -99,6 +106,7 @@ fn get_back(line: &str) -> i8 {
back
}

/// Calculate indentation properties of the current line
fn get_indent(line: &str, prev_indent: &Indent) -> Indent {
let diff = get_diff(line);
let back = get_back(line);
Expand All @@ -107,6 +115,7 @@ fn get_indent(line: &str, prev_indent: &Indent) -> Indent {
Indent { actual, visual }
}

/// Apply the correct indentation to a line
pub fn apply_indent(
line: &str,
linum_old: usize,
Expand Down
17 changes: 17 additions & 0 deletions src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Utilities for logging
use crate::colors::*;
use crate::Cli;
use env_logger::Builder;
Expand All @@ -9,17 +11,26 @@ use std::io::Write;
use std::path::Path;
use std::time::Instant;

/// Holds a log entry
#[derive(Debug)]
pub struct Log {
/// Log entry level
pub level: Level,
/// Time when the entry was logged
pub time: Instant,
/// File name associated with the entry
pub file: String,
/// Line number in the formatted file
pub linum_new: Option<usize>,
/// Line number in the original file
pub linum_old: Option<usize>,
/// Line content
pub line: Option<String>,
/// Entry-specific message
pub message: String,
}

/// Append a log to the logs list
fn record_log(
logs: &mut Vec<Log>,
level: Level,
Expand All @@ -41,6 +52,7 @@ fn record_log(
logs.push(log);
}

/// Append a file log to the logs list
pub fn record_file_log(
logs: &mut Vec<Log>,
level: Level,
Expand All @@ -50,6 +62,7 @@ pub fn record_file_log(
record_log(logs, level, file, None, None, None, message);
}

/// Append a line log to the logs list
pub fn record_line_log(
logs: &mut Vec<Log>,
level: Level,
Expand All @@ -70,6 +83,7 @@ pub fn record_line_log(
);
}

/// Get the formatting style of a log level
fn get_log_style(log_level: Level) -> String {
match log_level {
Info => CYAN.to_string(),
Expand All @@ -80,6 +94,7 @@ fn get_log_style(log_level: Level) -> String {
}
}

/// Parse the log level from the command line arguments
const fn get_log_level(args: &Cli) -> LevelFilter {
if args.trace {
LevelFilter::Trace
Expand All @@ -90,6 +105,7 @@ const fn get_log_level(args: &Cli) -> LevelFilter {
}
}

/// Start the logger
pub fn init_logger(args: &Cli) {
Builder::new()
.filter_level(get_log_level(args))
Expand All @@ -106,6 +122,7 @@ pub fn init_logger(args: &Cli) {
.init();
}

/// Display all of the logs collected
pub fn print_logs(mut logs: Vec<Log>) {
logs.sort_by_key(|l| {
(
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ use crate::write::*;
#[cfg(test)]
mod tests;

const TAB: i8 = 2;

#[cfg(target_family = "unix")]
/// Line ending for unix
const LINE_END: &str = "\n";

#[cfg(target_family = "windows")]
/// Line ending for Windows
const LINE_END: &str = "\r\n";

fn main() {
Expand Down
8 changes: 8 additions & 0 deletions src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
//! Utilities for reading the command line arguments
use clap::Parser;

/// Acceptable file extensions
const EXTENSIONS: [&str; 4] = [".tex", ".bib", ".sty", ".cls"];

/// Command line arguments
#[allow(missing_docs)]
#[allow(clippy::missing_docs_in_private_items)]
#[derive(Debug, Parser)]
#[command(version, about)]
pub struct Cli {
Expand All @@ -20,6 +26,7 @@ pub struct Cli {
}

impl Cli {
/// Ensure the provided arguments are consistent
pub fn resolve(&mut self) {
if self.trace {
self.verbose = true;
Expand All @@ -39,6 +46,7 @@ impl Cli {
}
}

/// Verify the file extension
pub fn check_extension_valid(file: &str) -> bool {
EXTENSIONS.iter().any(|e| file.ends_with(e))
}
12 changes: 12 additions & 0 deletions src/regexes.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
//! Regexes and matching utilities
use crate::LINE_END;
use lazy_static::lazy_static;
use regex::Regex;

/// Number of spaces for tabs and indents
pub const TAB: i8 = 2;

/// Match a LaTeX \item
pub const ITEM: &str = "\\item";
/// Match a LaTeX \begin{document}
pub const DOC_BEGIN: &str = "\\begin{document}";
/// Match a LaTeX \end{document}
pub const DOC_END: &str = "\\end{document}";
/// Match a LaTeX \begin{...}
pub const ENV_BEGIN: &str = "\\begin{";
/// Match a LaTeX \end{...}
pub const ENV_END: &str = "\\end{";

/// Names of LaTeX list environments
const LISTS: [&str; 5] = [
"itemize",
"enumerate",
Expand All @@ -16,6 +27,7 @@ const LISTS: [&str; 5] = [
"inventory",
];

/// Names of LaTeX verbatim environments
const VERBATIMS: [&str; 4] = ["verbatim", "Verbatim", "lstlisting", "minted"];

lazy_static! {
Expand Down
8 changes: 7 additions & 1 deletion src/subs.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
//! Utilities for performing text substitutions
use crate::comments::*;
use crate::format::*;
use crate::ignore::*;
use crate::logging::*;
use crate::regexes::*;
use crate::verbatim::*;
use crate::Cli;
use crate::{LINE_END, TAB};
use crate::{LINE_END};
use log::Level::Info;

/// Remove multiple line breaks
pub fn remove_extra_newlines(text: &str) -> String {
let double_line_end = format!("{LINE_END}{LINE_END}");
RE_NEWLINES.replace_all(text, double_line_end).to_string()
}

/// Replace tabs with spaces
pub fn remove_tabs(text: &str) -> String {
let replace = (0..TAB).map(|_| " ").collect::<String>();
text.replace('\t', &replace)
}

/// Remove trailing spaces from line endings
pub fn remove_trailing_spaces(text: &str) -> String {
RE_TRAIL.replace_all(text, LINE_END).to_string()
}

/// Ensure LaTeX environments begin on new lines
pub fn environments_new_line(
text: &str,
file: &str,
Expand Down
8 changes: 8 additions & 0 deletions src/verbatim.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
//! Utilities for ignoring verbatim environments
use crate::format::*;
use crate::logging::*;
use crate::regexes::*;
use log::Level::Warn;

/// Information on the verbatim state of a line
#[derive(Clone, Debug)]
pub struct Verbatim {
/// The verbatim depth of a line
pub actual: i8,
/// Whether the line is in a verbatim environment
pub visual: bool,
}

impl Verbatim {
/// Construct a new verbatim state
pub const fn new() -> Self {
Self {
actual: 0,
Expand All @@ -18,6 +24,7 @@ impl Verbatim {
}
}

/// Determine whether a line is in a verbatim environment
pub fn get_verbatim(
line: &str,
state: &State,
Expand All @@ -44,6 +51,7 @@ pub fn get_verbatim(
Verbatim { actual, visual }
}

/// Calculate total verbatim depth change
fn get_verbatim_diff(line: &str) -> i8 {
if line.contains(ENV_BEGIN)
&& VERBATIMS_BEGIN.iter().any(|r| line.contains(r))
Expand Down
9 changes: 8 additions & 1 deletion src/wrap.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
//! Utilities for wrapping long lines
use crate::comments::*;
use crate::format::*;
use crate::logging::*;
use crate::parse::*;
use log::Level::{Trace, Warn};

const WRAP_MIN: usize = 70;
/// Maximum allowed line length
const WRAP_MAX: usize = 80;
/// Length to which long lines are trimmed
const WRAP_MIN: usize = 70;

/// Check if a line needs wrapping
pub fn needs_wrap(line: &str, state: &State, args: &Cli) -> bool {
!args.keep
&& !state.verbatim.visual
&& !state.ignore.visual
&& (line.chars().count() > WRAP_MAX)
}

/// Find the best place to break a long line
fn find_wrap_point(line: &str) -> Option<usize> {
let mut wrap_point: Option<usize> = None;
let mut after_char = false;
Expand All @@ -34,6 +40,7 @@ fn find_wrap_point(line: &str) -> Option<usize> {
wrap_point
}

/// Wrap a long line into a short prefix and a suffix
pub fn apply_wrap(
line: &str,
state: &State,
Expand Down
Loading

0 comments on commit d91cda1

Please sign in to comment.