Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2201 (2023-08-11 21:16:46)

fix: Single # symbol in task line no longer treated as a tag
<!--- Provide a general summary of your changes in the Title above -->

# Description

Single # symbols in task lines are no longer treated as tags.

Now we require a tag to have at least one character after the #.

## Motivation and Context

Fixes https://github.com/obsidian-tasks-group/obsidian-tasks/issues/1969

## How has this been tested?

- Adding new tests in Tag-parsing and `group by tag` code. These failed before the bug was fixed.
- Manual exploratory testing in the demo vault.

## Screenshots (if appropriate)

### Before

![image](https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/44014115-5172-43b3-8997-cb0a98d214cf)


### After

![image](https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/cb90a455-ebbd-47d7-bc4d-4129848602d4)


## Types of changes


Changes visible to users:

- [x] **Bug fix** (prefix: `fix` - non-breaking change which fixes an issue)

Internal changes:

- [x] **Tests** (prefix: `test` - additions and improvements to unit tests and the smoke tests)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [ ] My change requires a change to the documentation.
- [ ] I have [updated the documentation](https://publish.obsidian.md/tasks-contributing/Documentation/About+Documentation) accordingly.
- [x] My change has adequate [Unit Test coverage](https://publish.obsidian.md/tasks-contributing/Testing/About+Testing).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://publish.obsidian.md/tasks-contributing) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follow this project's [contributing guide](https://publish.obsidian.md/tasks-contributing)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/src/Task.ts b/src/Task.ts
index 923760b2..ea175ace 100644
--- a/src/Task.ts
+++ b/src/Task.ts
@@ -93,7 +93,7 @@ export class TaskRegularExpressions {
     // EXAMPLE:
     // description: '#dog #car http://www/ddd#ere #house'
     // matches: #dog, #car, #house
-    public static readonly hashTags = /(^|\s)#[^ !@#$%^&*(),.?":{}|<>]*/g;
+    public static readonly hashTags = /(^|\s)#[^ !@#$%^&*(),.?":{}|<>]+/g;
     public static readonly hashTagsFromEnd = new RegExp(this.hashTags.source + '$');
 }
 


Test patch:
diff --git a/tests/Query/Filter/TagsField.test.ts b/tests/Query/Filter/TagsField.test.ts
index 36415a56..94454f2e 100644
--- a/tests/Query/Filter/TagsField.test.ts
+++ b/tests/Query/Filter/TagsField.test.ts
@@ -634,6 +634,7 @@ describe('grouping by tag', () => {
         ['- [ ] a #tag1', ['#tag1']],
         ['- [ ] a #tag1 #tag2', ['#tag1', '#tag2']],
         ['- [x] a', ['(No tags)']],
+        ['- [ ] be sure to count the # of tomatoes #gardening', ['#gardening']], // See #1969
     ])('task "%s" should have groups: %s', (taskLine: string, groups: string[]) => {
         // Arrange
         const grouper = new TagsField().createNormalGrouper().grouper;
diff --git a/tests/Task.test.ts b/tests/Task.test.ts
index b20efc54..45059eb6 100644
--- a/tests/Task.test.ts
+++ b/tests/Task.test.ts
@@ -394,6 +394,13 @@ describe('parsing tags', () => {
             extractedTags: ['#tagone'],
             globalFilter: '',
         },
+        {
+            // Single # character should not be treated as a tag - see issue 1969
+            markdownTask: '- [ ] count the # of tomatoes #gardening',
+            expectedDescription: 'count the # of tomatoes #gardening',
+            extractedTags: ['#gardening'],
+            globalFilter: '',
+        },
     ])(
         'should parse "$markdownTask" and extract "$extractedTags"',
         ({ markdownTask, expectedDescription, extractedTags, globalFilter }) => {