1
1
import slugify from '@sindresorhus/slugify' ;
2
2
import filenamify from 'filenamify' ;
3
3
import { ConfigureOptions , Environment , Template } from 'nunjucks' ;
4
- import { normalizePath , Plugin , TFile } from 'obsidian' ;
4
+ import { CachedMetadata , normalizePath , Plugin , TFile } from 'obsidian' ;
5
5
import spacetime from 'spacetime' ;
6
6
import * as YAML from 'yaml' ;
7
7
@@ -427,22 +427,22 @@ export default class ReadwiseMirror extends Plugin {
427
427
428
428
const metadata : ReadwiseMetadata = {
429
429
id : user_book_id ,
430
- title : title ,
430
+ title,
431
431
sanitized_title : sanitizedTitle ,
432
- author : author ,
433
- authorStr : authorStr ,
434
- document_note : document_note ,
435
- summary : summary ,
436
- category : category ,
437
- num_highlights : num_highlights ,
432
+ author : authors ,
433
+ authorStr,
434
+ document_note,
435
+ summary,
436
+ category,
437
+ num_highlights,
438
438
created : created ? this . formatDate ( created ) : '' ,
439
439
updated : updated ? this . formatDate ( updated ) : '' ,
440
440
cover_image_url : cover_image_url . replace ( 'SL200' , 'SL500' ) . replace ( 'SY160' , 'SY500' ) ,
441
441
highlights_url : readwise_url ,
442
- highlights : highlights ,
442
+ highlights,
443
443
last_highlight_at : last_highlight_at ? this . formatDate ( last_highlight_at ) : '' ,
444
- source_url : source_url ,
445
- unique_url : unique_url ,
444
+ source_url,
445
+ unique_url,
446
446
tags : this . formatTags ( book_tags ) ,
447
447
highlight_tags : this . formatTags ( highlightTags ) ,
448
448
tags_nohash : this . formatTags ( book_tags , true , "'" ) ,
@@ -451,12 +451,27 @@ export default class ReadwiseMirror extends Plugin {
451
451
452
452
// Escape specific fields used in frontmatter
453
453
// TODO: Tidy up code. It doesn't make sense to remove the frontmatter markers and then add them back
454
- const frontmatterYaml = YAML . parse (
455
- this . frontMatterTemplate
456
- . render ( this . escapeFrontmatter ( metadata , FRONTMATTER_TO_ESCAPE ) )
454
+ let frontmatterYaml ;
455
+ try {
456
+ const renderedTemplate = this . frontMatterTemplate . render (
457
+ this . escapeFrontmatter ( metadata , FRONTMATTER_TO_ESCAPE )
458
+ ) ;
459
+ const cleanedTemplate = renderedTemplate
457
460
. replace ( / ^ - - - \n / , '' )
458
- . replace ( / \n - - - \n * $ / , '' )
459
- ) ;
461
+ . replace ( / \n - - - \n * $ / , '' ) ;
462
+ frontmatterYaml = YAML . parse ( cleanedTemplate ) ;
463
+ } catch ( error ) {
464
+ if ( error instanceof YAML . YAMLParseError ) {
465
+ console . error ( 'Failed to parse YAML frontmatter:' , error . message ) ;
466
+ throw new Error ( `Invalid YAML frontmatter: ${ error . message } ` ) ;
467
+ } else if ( error instanceof Error ) {
468
+ console . error ( 'Error processing frontmatter template:' , error . message ) ;
469
+ throw new Error ( `Failed to process frontmatter: ${ error . message } ` ) ;
470
+ } else {
471
+ console . error ( 'Unknown error processing frontmatter:' , error ) ;
472
+ throw new Error ( 'Failed to process frontmatter due to unknown error' ) ;
473
+ }
474
+ }
460
475
const frontMatterContents = this . settings . frontMatter
461
476
? [ '---' , YAML . stringify ( frontmatterYaml , YAML_TOSTRING_OPTIONS ) , '---' ] . join ( '\n' )
462
477
: '' ;
@@ -714,19 +729,42 @@ export default class ReadwiseMirror extends Plugin {
714
729
this . notify . setStatusBarText ( `Readwise: Updated ${ this . lastUpdatedHumanReadableFormat ( ) } elsewhere` ) ;
715
730
}
716
731
717
- public ensureDedupPropertyInTemplate ( template : string ) : string {
718
- if ( ! this . settings . trackFiles ) return template ;
719
-
720
- const propertyName = this . settings . trackingProperty ;
721
- const propertyValue = `${ propertyName } : {{ highlights_url }}` ;
722
-
732
+ public addSyncPropertiesToFrontmatterTemplate ( template : string ) : string {
723
733
const lines = template . split ( '\n' ) ;
724
734
const frontmatterStart = lines . findIndex ( ( line ) => line . trim ( ) === '---' ) ;
725
735
const frontmatterEnd =
726
736
lines . slice ( frontmatterStart + 1 ) . findIndex ( ( line ) => line . trim ( ) === '---' ) + frontmatterStart + 1 ;
727
737
728
738
if ( frontmatterStart === - 1 || frontmatterEnd <= frontmatterStart ) return template ;
729
739
740
+ const propertiesToAdd : string [ ] = [ ] ;
741
+
742
+ // Add tracking property if enabled
743
+ if ( this . settings . trackFiles ) {
744
+ console . warn ( 'Adding tracking property to frontmatter template' ) ;
745
+ const trackingProperty = `${ this . settings . trackingProperty } : {{ highlights_url }}` ;
746
+ propertiesToAdd . push ( trackingProperty ) ;
747
+ }
748
+
749
+ // If no properties to add, return original template
750
+ if ( propertiesToAdd . length === 0 ) return template ;
751
+
752
+ // Remove any existing properties
753
+ const propertyNames = [
754
+ this . settings . trackingProperty ,
755
+ ] ;
756
+
757
+ const filteredLines = lines . filter ( ( line , index ) => {
758
+ if ( index < frontmatterStart || index > frontmatterEnd ) return true ;
759
+ return ! propertyNames . some ( prop => line . trim ( ) . startsWith ( `${ prop } :` ) ) ;
760
+ } ) ;
761
+
762
+ // Add new properties before closing ---
763
+ filteredLines . splice ( frontmatterEnd , 0 , ...propertiesToAdd ) ;
764
+
765
+ return filteredLines . join ( '\n' ) ;
766
+ }
767
+
730
768
// Update the frontmatter template with the sync properties
731
769
public updateFrontmatteTemplate ( ) {
732
770
this . frontMatterTemplate = new Template (
@@ -736,6 +774,13 @@ export default class ReadwiseMirror extends Plugin {
736
774
true
737
775
) ;
738
776
}
777
+
778
+ // Dedicated function to handle metadata change events
779
+ private onMetadataChange ( file : TFile ) {
780
+ const metadata : CachedMetadata = this . app . metadataCache . getFileCache ( file ) ;
781
+ if ( metadata && ! this . isSyncing ) {
782
+ console . log ( `Updated metadata cache for file: ${ file . path } : ${ JSON . stringify ( metadata ?. frontmatter ) } ` ) ;
783
+ }
739
784
}
740
785
741
786
async onload ( ) {
0 commit comments