@@ -25,21 +25,103 @@ const COLLAPSE_BLOCKS = true; // FIXME: this should be a setting
2525
2626/** This function is responsible for converting a KOReader metadata data structure into a Logseq block. */
2727function metadata_to_block ( metadata : any ) : IBatchBlock | null {
28- let bookmarks : IBatchBlock [ ] = [ ] ;
29-
3028 if ( metadata . doc_props === 'object' && Object . keys ( metadata . doc_props ) . length === 0 ) {
3129 return null ;
3230 }
3331
32+ if ( ! metadata . annotations ) {
33+ return handle_bookmarks_metadata ( metadata ) ;
34+ } else {
35+ return handle_annotations_metadata ( metadata ) ;
36+ }
37+ }
38+
39+ function handle_annotations_metadata ( metadata : any ) : IBatchBlock | null {
40+ if ( typeof metadata . annotations === 'object' && Object . keys ( metadata . annotations ) . length === 0 ) {
41+ return null ;
42+ }
43+
44+ let bookmarks : IBatchBlock [ ] = [ ] ;
45+
46+ let authors = metadata . doc_props . authors ;
47+ if ( authors ) {
48+ authors = authors . replace ( / \\ \n / g, ', ' ) ; // this seems to be how KOReader stores multiple authors; at least from Calibre
49+ }
50+
51+ if ( ! metadata . annotations ) {
52+ return {
53+ content : `## ${ metadata . doc_props . title } ` ,
54+ properties : {
55+ 'authors' : authors ,
56+ 'description' : truncateString ( metadata . doc_props . description , MAXIMUM_DESCRIPTION_LENGTH ) ,
57+ 'language' : metadata . doc_props . language ,
58+ }
59+ }
60+ }
61+
62+ for ( const annotation of metadata . annotations ) {
63+ let personal_note : IBatchBlock [ ] = [ ] ;
64+ if ( annotation . note ) {
65+ personal_note . push ( {
66+ content : annotation . note . replace ( '-' , '\\-' ) ,
67+ } ) ;
68+ }
69+
70+ let text_content : string = "> (no text available)" ;
71+ if ( ! annotation . pos0 ) {
72+ text_content = "> Page bookmark" ;
73+ } else if ( annotation . text ) {
74+ text_content = `> ${ annotation . text . replace ( '-' , '\\-' ) } ` ; // escape dashes; they're used for lists in logseq
75+ }
76+
77+ let annotation_date : string = annotation . datetime ;
78+ if ( annotation . datetime_updated ) {
79+ annotation_date = annotation . datetime_updated ;
80+ }
81+
82+ bookmarks . push (
83+ {
84+ content : text_content ,
85+ properties : {
86+ 'datetime' : annotation_date ,
87+ 'page' : annotation . pageno ,
88+ 'chapter' : annotation . chapter ,
89+ 'collapsed' : COLLAPSE_BLOCKS && personal_note . length > 0 ,
90+ } ,
91+ children : personal_note
92+ }
93+ )
94+ }
95+
96+ return {
97+ content : `## ${ metadata . doc_props . title } ` ,
98+ properties : {
99+ 'authors' : authors ,
100+ 'description' : truncateString ( metadata . doc_props . description , MAXIMUM_DESCRIPTION_LENGTH ) ,
101+ 'language' : metadata . doc_props . language ,
102+ 'collapsed' : COLLAPSE_BLOCKS ,
103+ } ,
104+ children : [
105+ {
106+ content : `### Bookmarks` ,
107+ children : bookmarks
108+ }
109+ ]
110+ }
111+ }
112+
113+ function handle_bookmarks_metadata ( metadata : any ) : IBatchBlock | null {
34114 if ( typeof metadata . bookmarks === 'object' && Object . keys ( metadata . bookmarks ) . length === 0 ) {
35115 return null ;
36116 }
37117
118+ let bookmarks : IBatchBlock [ ] = [ ] ;
119+
38120 let authors = metadata . doc_props . authors ;
39121 if ( authors ) {
40122 authors = authors . replace ( / \\ \n / g, ', ' ) ; // this seems to be how KOReader stores multiple authors; at least from Calibre
41123 }
42-
124+
43125 if ( ! metadata . bookmarks ) {
44126 return {
45127 content : `## ${ metadata . doc_props . title } ` ,
@@ -121,7 +203,7 @@ function lua_to_block(text: string): IBatchBlock | null {
121203 const subtarget = target . value . fields [ subfield ] ;
122204 if ( subtarget . value . type === "TableConstructorExpression" ) {
123205 const sub_dictionary = { } ;
124-
206+
125207 for ( const subsubfield in subtarget . value . fields ) {
126208 const subsubtarget = subtarget . value . fields [ subsubfield ] ;
127209 const subkey = subsubtarget . key . raw . replace ( / " / g, '' ) ;
@@ -187,14 +269,14 @@ function main () {
187269 async syncKOReader ( ) {
188270 const info = await logseq . App . getUserConfigs ( )
189271 if ( loading ) return
190-
272+
191273 const pageName = '_logseq-koreader-sync'
192274 const syncTimeLabel = ( new Date ( ) ) . toLocaleString ( ) // date and time as of now
193-
275+
194276 logseq . App . pushState ( 'page' , { name : pageName } )
195-
277+
196278 await delay ( 300 ) // wait for our UI elements to exist. FIXME: replace with check/sleep loop
197-
279+
198280 loading = true
199281
200282 const currentPage = await logseq . Editor . getCurrentPage ( )
@@ -226,7 +308,7 @@ function main () {
226308 }
227309
228310 let directoryHandle : any = await getStorage ( 'logseq_koreader_sync__directoryHandle' ) ;
229-
311+
230312 let permission ;
231313 if ( directoryHandle ) {
232314 permission = await verifyPermission ( directoryHandle ) ;
@@ -245,7 +327,7 @@ function main () {
245327 return ;
246328 }
247329 setStorage ( 'logseq_koreader_sync__directoryHandle' , directoryHandle ) ;
248- }
330+ }
249331
250332 if ( ! directoryHandle ) {
251333 console . error ( 'No directory selected / found.' )
@@ -308,7 +390,7 @@ function main () {
308390 }
309391
310392 // Has this been synced before?
311- if ( key in existingBlocks ) {
393+ if ( key in existingBlocks ) {
312394 const existing_block = await logseq . Editor . getBlock ( existingBlocks [ key ] ) ;
313395 if ( existing_block === null ) {
314396 console . error ( "Block not found, but we also just found it - which is pretty weird: " , existingBlocks [ key ] ) ;
@@ -360,7 +442,7 @@ function main () {
360442 // existing bookmark, check personal note
361443 if ( key in existing_bookmarks ) {
362444 let existing_bookmark = await logseq . Editor . getBlock ( existing_bookmarks [ key ] ) ;
363-
445+
364446 // personal note exists in graph
365447 if ( existing_bookmark ! . children && existing_bookmark ! . children ! . length > 0 ) {
366448 let existing_note = existing_bookmark ! . children ! [ 0 ] ;
@@ -376,7 +458,7 @@ function main () {
376458 await logseq . Editor . updateBlock ( existing_note [ 1 ] as string , bookmark . children ! [ 0 ] . content ) ;
377459 }
378460 }
379- }
461+ }
380462 // personal note does not exist in graph
381463 else {
382464 // add it
@@ -386,7 +468,7 @@ function main () {
386468 } )
387469 }
388470 }
389- }
471+ }
390472 // new bookmark, add it
391473 else {
392474 await logseq . Editor . insertBatchBlock ( existing_bookmark_block_uuid , [ bookmark ] , {
@@ -404,7 +486,7 @@ function main () {
404486 }
405487
406488 await logseq . Editor . updateBlock ( targetBlock ! . uuid , `# 📚 LKRS: KOReader - Sync Initiated at ${ syncTimeLabel } ` )
407-
489+
408490 syncProgress . destruct ( ) ;
409491 loading = false
410492 }
@@ -421,4 +503,4 @@ function main () {
421503}
422504
423505// bootstrap
424- logseq . ready ( main ) . catch ( console . error )
506+ logseq . ready ( main ) . catch ( console . error )
0 commit comments