diff --git a/Cargo.lock b/Cargo.lock index 4e9212d..ad8a434 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,7 +168,7 @@ dependencies = [ [[package]] name = "todos" -version = "0.1.0" +version = "0.1.1" dependencies = [ "clap", "glob", diff --git a/Cargo.toml b/Cargo.toml index c1ef24e..09aac69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "todos" -version = "0.1.0" +version = "0.1.1" edition = "2021" authors = ["Samuel Ć tancl "] description = "An intuitive system for organizing TODOs in code" diff --git a/samples/README.md b/samples/README.md index c7a5dcb..1357a78 100644 --- a/samples/README.md +++ b/samples/README.md @@ -26,3 +26,20 @@ def - abc - def + ``` + #!/bin/bash + + # call foo with bar argument + foo bar + #comment without space + ``` + +#Example script: +``` +#!/bin/bash + +# call foo with bar argument +foo bar + +#comment without space +``` diff --git a/samples/todo.md b/samples/todo.md index 1e20633..f86f1e1 100644 --- a/samples/todo.md +++ b/samples/todo.md @@ -10,3 +10,15 @@ ## Responsivity - abc - [ ] def + ``` + # make this work + foo bar + #foo bar + ``` + +#example +``` +# make this work +foo bar +#foo bar +``` diff --git a/src/scan.rs b/src/scan.rs index c5073aa..6d6e8fb 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -274,13 +274,31 @@ pub fn scan_dir(dir: &Path, entries: &mut Vec, excludes: &mut Vec) -> io::Result<()> { let str = fs::read_to_string(path)?; let mut current_category: Option<&str> = None; + let mut in_code_block = false; // This can produce: // - generic todos (above any category) // - category todos (below a ## category heading) // - priority todos (priority keyword part of the line) 'line: for (line_num, line) in str.lines().enumerate() { - if line.starts_with('#') { + if line.starts_with("```") { + // If we are in an *unindented* code block, we ignore lines + // starting with # - they cannot be headings. Indented + // code blocks are irrelevant. + in_code_block = ! in_code_block; + continue; + } + + // We need the line to start with # followed by spaces. So we cannot check just for '#' + // There's also no real need for any complex logic iterating over the line's characters, + // we can just check reasonable heading hierarchy like this. Anything else is unlikely. + if ! in_code_block && (false + || line.starts_with("# ") + || line.starts_with("## ") + || line.starts_with("### ") + || line.starts_with("#### ") + || line.starts_with("##### ") + ) { current_category = Some(line.split_once("# ").unwrap().1); continue; @@ -338,13 +356,31 @@ pub fn scan_todo_file(path: &Path, entries: &mut Vec) -> io::Result<()> { pub fn scan_readme_file(path: &Path, entries: &mut Vec) -> io::Result<()> { let str = fs::read_to_string(path)?; let mut in_todo_section = false; + let mut in_code_block = false; // This can produce: // - generic todos (above any category) // - category todos (below a ## category heading) todo@real add this logic and update README.md // - priority todos (priority keyword part of the line) 'line: for (line_num, line) in str.lines().enumerate() { - if line.starts_with('#') { + if line.starts_with("```") { + // If we are in an *unindented* code block, we ignore lines + // starting with # - they cannot be headings. Indented + // code blocks are irrelevant. + in_code_block = ! in_code_block; + continue; + } + + // We need the line to start with # followed by spaces. So we cannot check just for '#' + // There's also no real need for any complex logic iterating over the line's characters, + // we can just check reasonable heading hierarchy like this. Anything else is unlikely. + if ! in_code_block && (false + || line.starts_with("# ") + || line.starts_with("## ") + || line.starts_with("### ") + || line.starts_with("#### ") + || line.starts_with("##### ") + ) { let section = line.split_once("# ").unwrap().1; let cleaned_section = section.to_lowercase().trim_end_matches(':').trim().to_string();