@@ -1388,26 +1388,61 @@ export class TaskManager extends Component {
13881388 // Create the task markdown with the correct list marker
13891389 const useDataviewFormat =
13901390 this . plugin . settings . preferMetadataFormat === "dataview" ;
1391- // Start with the basic task using the extracted list marker
1392- let newTaskLine = `${ indentation } ${ listMarker } [ ] ${ completedTask . content } ` ;
13931391
1394- // Add metadata based on format preference
1395- const metadata = [ ] ;
1396-
1397- // Create sets to track existing project and context tags
1398- const existingProjectTags = new Set < string > ( ) ;
1399- const existingContextTags = new Set < string > ( ) ;
1392+ // Extract clean content without any existing tags, project tags, or context tags
1393+ let cleanContent = completedTask . content ;
14001394
1395+ // Remove all tags from the content to avoid duplication
14011396 if ( completedTask . tags && completedTask . tags . length > 0 ) {
1402- completedTask . tags . forEach ( ( tag ) => {
1403- if ( tag . startsWith ( "#project/" ) ) {
1404- existingProjectTags . add ( tag . substring ( "#project/" . length ) ) ;
1405- } else if ( tag . startsWith ( "@" ) ) {
1406- existingContextTags . add ( tag . substring ( 1 ) ) ;
1407- }
1408- } ) ;
1397+ // Get a unique list of tags to avoid processing duplicates
1398+ const uniqueTags = [ ...new Set ( completedTask . tags ) ] ;
1399+
1400+ // Remove each tag from the content
1401+ for ( const tag of uniqueTags ) {
1402+ // Create a regex that looks for the tag preceded by whitespace or at start, and followed by word boundary
1403+ const tagRegex = new RegExp (
1404+ `(^|\\s)${ tag . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) } \\b` ,
1405+ "g"
1406+ ) ;
1407+ cleanContent = cleanContent . replace ( tagRegex , " " ) . trim ( ) ;
1408+ }
14091409 }
14101410
1411+ // Remove project tags that might not be in the tags array
1412+ if ( completedTask . project ) {
1413+ const projectTag = `#project/${ completedTask . project } ` ;
1414+ const projectTagRegex = new RegExp (
1415+ `(^|\\s)${ projectTag . replace (
1416+ / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g,
1417+ "\\$&"
1418+ ) } \\b`,
1419+ "g"
1420+ ) ;
1421+ cleanContent = cleanContent . replace ( projectTagRegex , " " ) . trim ( ) ;
1422+ }
1423+
1424+ // Remove context tags that might not be in the tags array
1425+ if ( completedTask . context ) {
1426+ const contextTag = `@${ completedTask . context } ` ;
1427+ const contextTagRegex = new RegExp (
1428+ `(^|\\s)${ contextTag . replace (
1429+ / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g,
1430+ "\\$&"
1431+ ) } \\b`,
1432+ "g"
1433+ ) ;
1434+ cleanContent = cleanContent . replace ( contextTagRegex , " " ) . trim ( ) ;
1435+ }
1436+
1437+ // Normalize whitespace
1438+ cleanContent = cleanContent . replace ( / \s + / g, " " ) . trim ( ) ;
1439+
1440+ // Start with the basic task using the extracted list marker and clean content
1441+ let newTaskLine = `${ indentation } ${ listMarker } [ ] ${ cleanContent } ` ;
1442+
1443+ // Add metadata based on format preference
1444+ const metadata = [ ] ;
1445+
14111446 // 1. Tags (excluding project/context tags that are handled separately)
14121447 if ( completedTask . tags && completedTask . tags . length > 0 ) {
14131448 const tagsToAdd = completedTask . tags . filter ( ( tag ) => {
@@ -1424,7 +1459,11 @@ export class TaskManager extends Component {
14241459 } ) ;
14251460
14261461 if ( tagsToAdd . length > 0 ) {
1427- metadata . push ( ...tagsToAdd ) ;
1462+ // Ensure uniqueness and proper formatting
1463+ const uniqueTagsToAdd = [ ...new Set ( tagsToAdd ) ] . map ( ( tag ) =>
1464+ tag . startsWith ( "#" ) ? tag : `#${ tag } `
1465+ ) ;
1466+ metadata . push ( ...uniqueTagsToAdd ) ;
14281467 }
14291468 }
14301469
@@ -1446,15 +1485,10 @@ export class TaskManager extends Component {
14461485 if ( useDataviewFormat ) {
14471486 metadata . push ( `[context:: ${ completedTask . context } ]` ) ;
14481487 } else {
1449- // 仅当上下文不在已有上下文标签集合中时才添加
1450- if ( ! existingContextTags . has ( completedTask . context ) ) {
1451- metadata . push ( `@${ completedTask . context } ` ) ;
1452- } else {
1453- // 上下文已在标签中,确保它被添加到标签列表
1454- const contextTag = `@${ completedTask . context } ` ;
1455- if ( ! metadata . includes ( contextTag ) ) {
1456- metadata . push ( contextTag ) ;
1457- }
1488+ const contextTag = `@${ completedTask . context } ` ;
1489+ // Only add context tag if it's not already in the metadata
1490+ if ( ! metadata . includes ( contextTag ) ) {
1491+ metadata . push ( contextTag ) ;
14581492 }
14591493 }
14601494 }
0 commit comments