Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add various optional functionality #134

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions src/get-todos.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,25 @@ class TodoParser {
// Boolean that encodes whether nested items should be rolled over
#withChildren;

constructor(lines, withChildren) {
// Boolean that encodes whether headings should be rolled over.
#withHeadings;

// Boolean that encodes whether bullets should be rolled over.
#withBullets;

// Boolean that encodes whether children should have existing filters applied
#filterChildren;

// Boolean that encodes whether completed children should be rolled over. Only relevant when #withChildren is true and #filterChildren is true.
#withCompletedChildren;

constructor(lines, withChildren, withHeadings, withBullets, filterChildren, withCompletedChildren) {
this.#lines = lines;
this.#withChildren = withChildren;
this.#withHeadings = withHeadings;
this.#withBullets = withBullets;
this.#filterChildren = filterChildren;
this.#withCompletedChildren = withCompletedChildren;
}

// Returns true if string s is a todo-item
Expand All @@ -19,6 +35,24 @@ class TodoParser {
return r.test(s);
}

// Returns true if the string is a completed todo-item
#isCompletedTodo(s) {
const r = new RegExp(`\\s*[${this.bulletSymbols.join("")}] \\[[xX-]\\].*`, "g"); // /\s*[-*+] \[[^xX-]\].*/g;
return r.test(s);
}

// Returns true if the string is a bulleted list item (optionally included as a todo-item)
#isBullet(s) {
const r = new RegExp(`\\s*[${this.bulletSymbols.join("")}] (?!\\[[^xX]]).*`, "g"); // /\s*[-*+] \[[^xX-]\].*/g;
return r.test(s);
}

// Returns true if the string is a heading
#isHeading(s) {
const h = new RegExp(`\\s*#+.*`, "g");
return h.test(s);
}

// Returns true if line after line-number `l` is a nested item
#hasChildren(l) {
if (l + 1 >= this.#lines.length) {
Expand Down Expand Up @@ -56,17 +90,39 @@ class TodoParser {
return this.#lines[l].search(/\S/);
}

isRelevant(line) {
if (this.#isTodo(line)) {
return true;
}

if (this.#withHeadings && this.#isHeading(line)) {
return true;
}

if (this.#withBullets) {
return this.#isBullet(line);
}

return false;
}

// Returns a list of strings that represents all the todos along with there potential children
getTodos() {
let todos = [];
for (let l = 0; l < this.#lines.length; l++) {
const line = this.#lines[l];
if (this.#isTodo(line)) {
if (this.isRelevant(line)) {
todos.push(line);
if (this.#withChildren && this.#hasChildren(l)) {
const cs = this.#getChildren(l);
const children = this.#getChildren(l);
const cs = children.filter(c => {
if (!this.#withCompletedChildren && this.#isCompletedTodo(c)) {
return false;
}
return (!this.#filterChildren || this.isRelevant(c));
});
todos = [...todos, ...cs];
l += cs.length;
l += children.length;
}
}
}
Expand All @@ -75,7 +131,7 @@ class TodoParser {
}

// Utility-function that acts as a thin wrapper around `TodoParser`
export const getTodos = ({ lines, withChildren = false }) => {
const todoParser = new TodoParser(lines, withChildren);
export const getTodos = ({ lines, withChildren = false , withHeadings = false, withBullets = false, filterChildren = false, withCompletedChildren = true}) => {
const todoParser = new TodoParser(lines, withChildren, withHeadings, withBullets, filterChildren, withCompletedChildren);
return todoParser.getTodos();
};
182 changes: 180 additions & 2 deletions src/get-todos.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ test("single done todo element should not return itself", () => {
const result = getTodos({ lines });

// THEN
const todos = [""];
const todos = [];
expect(result).toStrictEqual(todos);
});

Expand All @@ -45,7 +45,7 @@ test("single canceled todo element should not return itself", () => {
const result = getTodos({ lines });

// THEN
const todos = [""];
const todos = [];
expect(result).toStrictEqual(todos);
});

Expand Down Expand Up @@ -128,6 +128,30 @@ test("get todos (with alternate symbols and partially checked todos) with childr
expect(todos).toStrictEqual(result);
});

test("get todos (with alternate symbols and partially checked todos) with children without completed children", function () {
// GIVEN
const lines = [
"+ [x] Completed TODO",
" + [ ] Next",
" * some stuff",
"* [ ] Another one",
" - [x] Completed child",
" + another child",
"- this isn't copied",
];

// WHEN
const todos = getTodos({ lines: lines, withChildren: true, withCompletedChildren: false});

// THEN
const result = [
" + [ ] Next",
"* [ ] Another one",
" + another child",
];
expect(todos).toStrictEqual(result);
});

test("get todos (with default dash prefix and finished todos) with children", function () {
// GIVEN
const lines = [
Expand Down Expand Up @@ -199,6 +223,7 @@ test("get todos with correct alternate checkbox children", function () {
const result = [
"- [ ] TODO",
" - [ ] Next",
" - [x] Completed task",
" - some stuff",
"- [ ] Another one",
" - [ ] Another child",
Expand All @@ -207,6 +232,38 @@ test("get todos with correct alternate checkbox children", function () {
];
expect(todos).toStrictEqual(result);
});

test("get todos with correct alternate checkbox children without finished subtasks", function () {
// GIVEN
const lines = [
"- [ ] TODO",
" - [ ] Next",
" - [x] Completed task",
" - some stuff",
"- [ ] Another one",
" - [ ] Another child",
" - [/] More children",
" - [x] Completed children",
" - another child",
"- this isn't copied",
];

// WHEN
const todos = getTodos({ lines: lines, withChildren: true, withCompletedChildren: false});

// THEN
const result = [
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"- [ ] Another one",
" - [ ] Another child",
" - [/] More children",
" - another child",
];
expect(todos).toStrictEqual(result);
});

test("get todos with children doesn't fail if child at end of list", () => {
// GIVEN
const lines = [
Expand Down Expand Up @@ -299,3 +356,124 @@ test("get todos doesn't add intermediate other elements", () => {
];
expect(todos).toStrictEqual(result);
});

test("get todos doesn't add headings", () => {
// GIVEN
const lines = [
"# Some title",
"",
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"",
"## Some title",
"",
"Some text",
"...that continues here",
"",
"- Here is a bullet item",
"- Here is another bullet item",
"1. Here is a numbered list item",
"- [ ] Another one",
" - [ ] More children",
" - another child",
];

// WHEN
const todos = getTodos({ lines, withChildren: true, withBullets: false, filterChildren: true, withHeadings: true});

// THEN
const result = [
"# Some title",
"- [ ] TODO",
" - [ ] Next",
"## Some title",
"- [ ] Another one",
" - [ ] More children",
];
expect(todos).toStrictEqual(result);
});

test("get todos doesn't add headings and sub bullets", () => {
// GIVEN
const lines = [
"# Some title",
"",
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"",
"## Some title",
"",
"Some text",
"...that continues here",
"",
"- Here is a bullet item that is a valid child",
"- Here is another bullet item",
"1. Here is a numbered list item",
"- [ ] Another one",
" - [ ] More children",
" - another child",
];

// WHEN
const todos = getTodos({ lines, withChildren: true, withBullets: true, filterChildren: true, withHeadings: true});

// THEN
const result = [
"# Some title",
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"## Some title",
"- Here is a bullet item that is a valid child",
"- Here is another bullet item",
"- [ ] Another one",
" - [ ] More children",
" - another child",
];
expect(todos).toStrictEqual(result);
});

test("get todos includes bullets", () => {
// GIVEN
const lines = [
"# Some title",
"",
"- bullet",
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"",
"## Some title",
"",
"Some text",
"...that continues here",
"",
"- Here is a bullet item that is a valid child",
"- Here is another bullet item",
"1. Here is a numbered list item",
"- [ ] Another one",
" - [ ] More children",
" - another child",
];

// WHEN
const todos = getTodos({ lines, withChildren: true, withBullets: true, filterChildren: false, withHeadings: true});

// THEN
const result = [
"# Some title",
"- bullet",
"- [ ] TODO",
" - [ ] Next",
" - some stuff",
"## Some title",
"- Here is a bullet item that is a valid child",
"- Here is another bullet item",
"- [ ] Another one",
" - [ ] More children",
" - another child",
];
expect(todos).toStrictEqual(result);
});
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default class RolloverTodosPlugin extends Plugin {
removeEmptyTodos: false,
rolloverChildren: false,
rolloverOnFileCreate: true,
rolloverHeadings: false,
rolloverBullets: false,
filterChildren: false,
rolloverCompletedChildren: true,
};
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
Expand Down Expand Up @@ -126,6 +130,10 @@ export default class RolloverTodosPlugin extends Plugin {
return getTodos({
lines: dnLines,
withChildren: this.settings.rolloverChildren,
withHeadings: this.settings.rolloverHeadings,
withBullets: this.settings.rolloverBullets,
filterChildren: this.settings.filterChildren,
withCompletedChildren: this.settings.rolloverCompletedChildren,
});
}

Expand Down