diff --git a/src/main/w3c/annotation/annotationModel.type.ts b/src/main/w3c/annotation/annotationModel.type.ts new file mode 100644 index 0000000000..f96a0a6dd2 --- /dev/null +++ b/src/main/w3c/annotation/annotationModel.type.ts @@ -0,0 +1,88 @@ +// ==LICENSE-BEGIN== +// Copyright 2017 European Digital Reading Lab. All rights reserved. +// Licensed to the Readium Foundation under one or more contributor license agreements. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// ==LICENSE-END== + +export interface IW3CAnnotationModel { + "@context": string; + id: string; + created: string; + modified: string; + type: string; + hash: string; + body: { + type: string; + value: string; + format: string; + color: string; + textDirection?: string; + language?: string; + }; + target: { + source: string; + meta: { + headings: { + level: number; + txt: string; + }[]; + page: string; + }; + selector: ( + | { + type: "TextQuoteSelector"; + exact: string; + prefix: string; + suffix: string; + } + | { + type: "ProgressionSelector"; + value: number; + } + | { + type: "DomRangeSelector"; + startContainerElementCssSelector: string; + startContainerChildTextNodeIndex: number; + startOffset: number; + endContainerElementCssSelector: string; + endContainerChildTextNodeIndex: number; + endOffset: number; + } + | { + type: "FragmentSelector"; + conformsTo: string; + value: string; + } + )[]; + }; +} + +interface Generator { + id: string; + type: string; + name: string; + homepage: string; +} + +interface About { + "dc:identifier": string[]; + "dc:format": string; + "dc:title": string; + "dc:publisher": string; + "dc:creator": string; + "dc:date": string; + "dc:source"?: string; +} + +export interface IW3CAnnotationModelSet { + "@context": string; + id: string; + type: string; + generator: Generator; + generated: string; + label: string; + about: About; + total: number, + items: IW3CAnnotationModel[]; +} diff --git a/src/main/w3c/annotation/converter.ts b/src/main/w3c/annotation/converter.ts new file mode 100644 index 0000000000..72d52ab006 --- /dev/null +++ b/src/main/w3c/annotation/converter.ts @@ -0,0 +1,113 @@ +// ==LICENSE-BEGIN== +// Copyright 2017 European Digital Reading Lab. All rights reserved. +// Licensed to the Readium Foundation under one or more contributor license agreements. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// ==LICENSE-END== + +import { IAnnotationState } from "readium-desktop/common/redux/states/annotation"; +import { IW3CAnnotationModel, IW3CAnnotationModelSet } from "./annotationModel.type"; +import { v4 as uuidv4 } from "uuid"; +import { _APP_VERSION } from "readium-desktop/preprocessor-directives"; + +function rgbToHex(color: { red: number; green: number; blue: number }): string { + const { red, green, blue } = color; + const redHex = Math.min(255, Math.max(0, red)).toString(16).padStart(2, "0"); + const greenHex = Math.min(255, Math.max(0, green)).toString(16).padStart(2, "0"); + const blueHex = Math.min(255, Math.max(0, blue)).toString(16).padStart(2, "0"); + return `#${redHex}${greenHex}${blueHex}`; +} + +export function convertAnnotationToW3CAnnotationModel(annotation: IAnnotationState): IW3CAnnotationModel { + + const currentDate = new Date(); + const dateString: string = currentDate.toISOString(); + const { uuid, hash, color, def } = annotation; + const { selectionInfo, locator, headings, epubPage } = def; + const { cleanText, rawText, rawBefore, rawAfter } = selectionInfo; + const { href } = locator; + + return { + "@context": "http://www.w3.org/ns/anno.jsonld", + id: uuid ? "urn:uuid:" + uuid : "", + created: dateString, + modified: dateString, + type: "Annotation", + hash: hash || "", + body: { + type: "TextualBody", + value: cleanText || "", + format: "text/plain", + color: rgbToHex(color), + // textDirection: "ltr", + // language: "fr", + }, + target: { + source: href || "", + meta: { + headings: (headings || []).map(({ txt, level }) => ({ level, txt })), + page: epubPage || "", + }, + selector: [ + { + type: "TextQuoteSelector", + exact: rawText || "", + prefix: rawBefore || "", + suffix: rawAfter || "", + }, + { + type: "ProgressionSelector", + value: locator.locations?.progression || 0, + }, + { + type: "DomRangeSelector", + startContainerElementCssSelector: selectionInfo?.rangeInfo?.startContainerElementCssSelector || "", + startContainerChildTextNodeIndex: selectionInfo?.rangeInfo?.startContainerChildTextNodeIndex || 0, + startOffset: selectionInfo?.rangeInfo?.startOffset || 0, + endContainerElementCssSelector: selectionInfo?.rangeInfo?.endContainerElementCssSelector || "", + endContainerChildTextNodeIndex: selectionInfo?.rangeInfo?.endContainerChildTextNodeIndex || 0, + endOffset: selectionInfo?.rangeInfo?.endOffset || 0, + }, + { + type: "FragmentSelector", + conformsTo: "http://www.idpf.org/epub/linking/cfi/epub-cfi.html", + value: `epubcfi(${selectionInfo?.rangeInfo?.cfi || locator.locations?.cfi || ""})`, + }, + ], + }, + }; +} + +export function convertAnnotationListToW3CAnnotationModelSel(annotationArray: IAnnotationState[], + publicationMetadata: { identiferArrayString: string[], mimeType: string, title: string, publisher: string, creator: string, dateYear: string, sourceIsbn: string }, +): IW3CAnnotationModelSet { + + const { identiferArrayString, mimeType, title, publisher, creator, dateYear, sourceIsbn } = publicationMetadata; + const currentDate = new Date(); + const dateString: string = currentDate.toISOString(); + + return { + "@context": "http://www.w3.org/ns/anno.jsonld", + id: "urn:uuid:" + uuidv4(), + type: "AnnotationSet", + generator: { + id: "https://github.com/edrlab/thorium-reader/releases/tag/v" + _APP_VERSION, + type: "Software", + name: _APP_VERSION, + homepage: "https://thorium.edrlab.org", + }, + generated: dateString, + label: "Annotations set", + about: { + "dc:identifier": identiferArrayString || [], + "dc:format": mimeType || "", + "dc:title": title || "", + "dc:publisher": publisher || "", + "dc:creator": creator || "", + "dc:date": dateYear || "", + "dc:source": sourceIsbn || "", + }, + total: annotationArray.length, + items: (annotationArray || []).map((v) => convertAnnotationToW3CAnnotationModel(v)), + }; +}