-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for importing KOReader & Calibre EPUB annotations
- Loading branch information
1 parent
c1a538a
commit d600ec5
Showing
9 changed files
with
367 additions
and
5 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { EpubCFI } from "epubjs"; | ||
import SectionRenderer from "../section-renderer"; | ||
import { lengthenCFI } from "../cfi"; | ||
|
||
export function calibreAnnotationToRange(annotation: CalibreAnnotation, sectionRenderers: SectionRenderer[]): Range | null { | ||
let sectionRenderer = sectionRenderers[annotation.spine_index]; | ||
if (!sectionRenderer) { | ||
return null; | ||
} | ||
|
||
// Calibre CFIs are basically valid EPUB CFIs, but they're missing the step | ||
// indirection part, and they have an extra leading /2 (first element child) | ||
// selector because they're relative to the root of the document instead of | ||
// its root element. | ||
// Some simple cleanup should make them parse correctly. | ||
let startCFI = new EpubCFI(lengthenCFI( | ||
sectionRenderer.section.cfiBase + '!' | ||
+ annotation.start_cfi.replace(/^\/2\//, '/'))); | ||
let endCFI = new EpubCFI(lengthenCFI( | ||
sectionRenderer.section.cfiBase + '!' | ||
+ annotation.end_cfi.replace(/^\/2\//, '/'))); | ||
try { | ||
let startRange = startCFI.toRange(sectionRenderer.container.ownerDocument, undefined, sectionRenderer.container); | ||
let endRange = endCFI.toRange(sectionRenderer.container.ownerDocument, undefined, sectionRenderer.container); | ||
startRange.setEnd(endRange.endContainer, endRange.endOffset); | ||
return startRange; | ||
} | ||
catch (e) { | ||
console.error(e); | ||
return null; | ||
} | ||
} | ||
|
||
export function parseAnnotationsFromCalibreMetadata(metadata: string) { | ||
let doc = new DOMParser().parseFromString(metadata, 'text/xml'); | ||
let annotationMetas = doc.querySelectorAll('meta[name="calibre:annotation"][content]'); | ||
let calibreAnnotations: CalibreAnnotation[] = []; | ||
for (let annotationMeta of annotationMetas) { | ||
let annotation; | ||
try { | ||
annotation = JSON.parse(annotationMeta.getAttribute('content')!); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
continue; | ||
} | ||
if (annotation.format !== 'EPUB' | ||
|| 'removed' in annotation.annotation && annotation.annotation.removed | ||
|| annotation.annotation.type !== 'highlight') { | ||
continue; | ||
} | ||
calibreAnnotations.push(annotation.annotation); | ||
} | ||
return calibreAnnotations; | ||
} | ||
|
||
export type CalibreAnnotation = { | ||
// There's more in the metadata, but these are all we need | ||
type: 'highlight'; | ||
spine_index: number; | ||
start_cfi: string; | ||
end_cfi: string; | ||
notes?: string; | ||
style?: { | ||
kind: 'color'; | ||
which: 'yellow' | 'green' | 'blue' | 'pink' | 'purple' | string; | ||
} | { | ||
kind: 'decoration'; | ||
which: 'wavy' | 'strikeout' | string; | ||
}; | ||
}; |
Oops, something went wrong.