diff --git a/README.md b/README.md
index 5622d01..ce59da7 100644
--- a/README.md
+++ b/README.md
@@ -40,11 +40,19 @@ Check Obsidian Help for more information about [Community plugins](https://help.
- `Cmd+P > Apple Books - Import Highlights: From a specific book...`
- **Ribbon**: Select the plugin icon in the Ribbon (left sidebar)
-## Template variables
+## Customization
+
+The plugin uses Handlebars and Markdown to customize the output of your highlights the way you want.
+
+### Template variables
- `{{{bookTitle}}}` - The title of the book.
- `{{bookId}}` - A unique identifier of the book. It is used to create a link to the book in Apple Books: `[Apple Books Link](ibooks://assetid/{{bookId}})`.
- `{{{bookAuthor}}}` - The author of the book.
+- `{{{bookGenre}}}` - The genre of the book.
+- `{{bookLanguage}}` - The language of the book.
+- `{{bookLastOpenedDate}}` - The date when you last opened the book.
+- `{{bookCoverUrl}}` - The URL of the book cover.
- `{{annotations}}` - An array of all the annotations in the book. You can use `{{annotations.length}}` to get the total number of annotations you made in the book. Each annotation has the following properties:
- `{{{chapter}}}` - The chapter of the highlight in the book. It may not be available for all highlights due to the initial formatting of the book.
- `{{{contextualText}}}` - The text surrounding the highlight to give you more context. For example:
@@ -52,12 +60,59 @@ Check Obsidian Help for more information about [Community plugins](https://help.
- If you highlight parts of two adjacent sentences, the `contextualText` will contain both sentences.
- `{{{highlight}}}` - The highlighted text.
- `{{{note}}}` - A note you added for the highlight.
+ - `{{highlightStyle}}` - The style of the highlight. It can be one of the following values:
+ - `0` (underline)
+ - `1` (green)
+ - `2` (blue)
+ - `3` (yellow)
+ - `4` (pink)
+ - `5` (violet)
+
> [!NOTE]
> When customizing the template, make sure to wrap variables with triple curly braces (`{{{variable}}}`) to avoid escaping the HTML characters in Markdown files (default behavior).
>
> If you want escaped output, use double curly braces: `{{variable}}`.
+### Templates
+
+#### Template with colored highlights
+
+![template colors](template-colors.png)
+
+```hbs
+Title:: 📕 {{{bookTitle}}}
+Author:: {{{bookAuthor}}}
+Genre:: {{#if bookGenre}}{{{bookGenre}}}{{else}}N/A{{/if}}
+Language:: {{#if bookLanguage}}{{bookLanguage}}{{else}}N/A{{/if}}
+Last Read:: {{dateFormat bookLastOpenedDate "YYYY-MM-DD hh:mm:ss A Z"}}
+Link:: [Apple Books Link](ibooks://assetid/{{bookId}})
+
+{{#if bookCoverUrl}}![Book Cover]({{{bookCoverUrl}}}){{/if}}
+
+## Annotations
+
+Number of annotations:: {{annotations.length}}
+
+{{#each annotations}}
+----
+
+- 📖 Chapter:: {{#if chapter}}{{{chapter}}}{{else}}N/A{{/if}}
+- 🔖 Context:: {{#if contextualText}}{{{contextualText}}}{{else}}N/A{{/if}}
+{{#if (eq highlightStyle "0")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "1")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "2")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "3")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "4")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "5")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+- 📝 Note:: {{#if note}}{{{note}}}{{else}}N/A{{/if}}
+- 📅 Highlight taken on:: {{dateFormat highlightCreationDate "YYYY-MM-DD hh:mm:ss A Z"}}
+- 📅 Highlight modified on:: {{dateFormat highlightModificationDate "YYYY-MM-DD hh:mm:ss A Z"}}
+
+{{/each}}
+```
+
+
## Contributing
Your feedback and ideas are more than welcome and highly appreciated! Join the discussion in the [Obsidian Forum](https://forum.obsidian.md/t/new-plugin-apple-books-import-highlights/76856).
diff --git a/main.ts b/main.ts
index 3d931cf..abb7755 100644
--- a/main.ts
+++ b/main.ts
@@ -1,6 +1,7 @@
import * as child_process from 'child_process';
import * as Handlebars from 'handlebars';
import { normalizePath, Notice, Plugin } from 'obsidian';
+import dayjs from 'dayjs';
import * as path from 'path';
import { promisify } from 'util';
import { DEFAULT_SETTINGS, IBookHighlightsSettingTab } from './src/settings';
@@ -66,7 +67,7 @@ export default class IBookHighlightsPlugin extends Plugin {
async getBooks(): Promise {
const IBOOK_LIBRARY = '~/Library/Containers/com.apple.iBooksX/Data/Documents/BKLibrary/BKLibrary-1-091020131601.sqlite';
const booksSql = `
- SELECT ZASSETID, ZTITLE, ZAUTHOR, ZGENRE
+ SELECT ZASSETID, ZTITLE, ZAUTHOR, ZGENRE, ZLANGUAGE, ZLASTOPENDATE, ZCOVERURL
FROM ZBKLIBRARYASSET
WHERE ZPURCHASEDATE IS NOT NULL`;
@@ -85,7 +86,7 @@ export default class IBookHighlightsPlugin extends Plugin {
async getAnnotations(): Promise {
const IBOOK_ANNOTATION_DB = '~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite';
const annotationsSql = `
- SELECT ZANNOTATIONASSETID, ZFUTUREPROOFING5, ZANNOTATIONREPRESENTATIVETEXT, ZANNOTATIONSELECTEDTEXT, ZANNOTATIONNOTE
+ SELECT ZANNOTATIONASSETID, ZFUTUREPROOFING5, ZANNOTATIONREPRESENTATIVETEXT, ZANNOTATIONSELECTEDTEXT, ZANNOTATIONNOTE, ZANNOTATIONCREATIONDATE, ZANNOTATIONMODIFICATIONDATE, ZANNOTATIONSTYLE
FROM ZAEANNOTATION
WHERE ZANNOTATIONSELECTEDTEXT IS NOT NULL
AND ZANNOTATIONDELETED IS 0`;
@@ -118,12 +119,19 @@ export default class IBookHighlightsPlugin extends Plugin {
bookTitle: normalizedBookTitle,
bookId: book.ZASSETID,
bookAuthor: book.ZAUTHOR,
+ bookGenre: book.ZGENRE,
+ bookLanguage: book.ZLANGUAGE,
+ bookLastOpenedDate: book.ZLASTOPENDATE,
+ bookCoverUrl: book.ZCOVERURL,
annotations: bookRelatedAnnotations.map(annotation => {
return {
chapter: annotation.ZFUTUREPROOFING5,
contextualText: annotation.ZANNOTATIONREPRESENTATIVETEXT,
highlight: annotation.ZANNOTATIONSELECTEDTEXT,
note: annotation.ZANNOTATIONNOTE,
+ highlightStyle: annotation.ZANNOTATIONSTYLE,
+ highlightCreationDate: annotation.ZANNOTATIONCREATIONDATE,
+ highlightModificationDate: annotation.ZANNOTATIONMODIFICATIONDATE
}
})
})
@@ -163,7 +171,18 @@ export default class IBookHighlightsPlugin extends Plugin {
await this.app.vault.createFolder(this.settings.highlightsFolder);
- highlights.forEach(async (highlight: CombinedHighlight) => {
+ highlights.forEach(async (highlight: CombinedHighlight) => {
+ // TODO: Consider moving to a separate file if there are several helpers to be added
+ Handlebars.registerHelper('eq', (a, b) => {
+ if (a == b) {
+ return this;
+ }
+ });
+
+ Handlebars.registerHelper('dateFormat', (date, format) => {
+ return dayjs('2001-01-01').add(date, 's').format(format);
+ });
+
const template = Handlebars.compile(this.settings.template);
const renderedTemplate = template(highlight);
diff --git a/manifest.json b/manifest.json
index 818fd5d..24395c6 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"id": "apple-books-import-highlights",
"name": "Apple Books - Import Highlights",
- "version": "1.1.1",
+ "version": "1.2.0",
"minAppVersion": "0.15.0",
"description": "Import your Apple Books highlights and notes to Obsidian.",
"author": "bandantonio",
diff --git a/package-lock.json b/package-lock.json
index 19f2e9d..a8ffd81 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,14 +1,15 @@
{
"name": "obsidian-apple-books-highlights-plugin",
- "version": "1.1.1",
+ "version": "1.2.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "obsidian-apple-books-highlights-plugin",
- "version": "1.1.1",
+ "version": "1.2.0",
"license": "MIT",
"dependencies": {
+ "dayjs": "^1.11.10",
"handlebars": "^4.7.8",
"sqlite3": "^5.1.7-rc.0"
},
@@ -1155,6 +1156,11 @@
"node": ">= 8"
}
},
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -4003,6 +4009,11 @@
"which": "^2.0.1"
}
},
+ "dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
diff --git a/package.json b/package.json
index 4c89a9c..1b29a30 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "obsidian-apple-books-highlights-plugin",
- "version": "1.1.1",
+ "version": "1.2.0",
"description": "Import highlights and notes from your Apple Books to Obsidian",
"main": "main.js",
"scripts": {
@@ -38,7 +38,8 @@
"typescript": "4.7.4"
},
"dependencies": {
+ "dayjs": "^1.11.10",
"handlebars": "^4.7.8",
"sqlite3": "^5.1.7-rc.0"
}
-}
\ No newline at end of file
+}
diff --git a/src/template.ts b/src/template.ts
index 91df0b6..fb82e59 100644
--- a/src/template.ts
+++ b/src/template.ts
@@ -1,7 +1,12 @@
const defaultTemplate = `Title:: 📕 {{{bookTitle}}}
Author:: {{{bookAuthor}}}
+Genre:: {{#if bookGenre}}{{{bookGenre}}}{{else}}N/A{{/if}}
+Language:: {{#if bookLanguage}}{{bookLanguage}}{{else}}N/A{{/if}}
+Last Read:: {{dateFormat bookLastOpenedDate "YYYY-MM-DD hh:mm:ss A Z"}}
Link:: [Apple Books Link](ibooks://assetid/{{bookId}})
+{{#if bookCoverUrl}}![Book Cover]({{{bookCoverUrl}}}){{/if}}
+
## Annotations
Number of annotations:: {{annotations.length}}
@@ -11,8 +16,15 @@ Number of annotations:: {{annotations.length}}
- 📖 Chapter:: {{#if chapter}}{{{chapter}}}{{else}}N/A{{/if}}
- 🔖 Context:: {{#if contextualText}}{{{contextualText}}}{{else}}N/A{{/if}}
-- 🎯 Highlight:: {{{highlight}}}
+{{#if (eq highlightStyle "0")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "1")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "2")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "3")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "4")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
+{{#if (eq highlightStyle "5")}}- 🎯 Highlight:: {{{highlight}}}{{/if}}
- 📝 Note:: {{#if note}}{{{note}}}{{else}}N/A{{/if}}
+- 📅 Highlight taken on:: {{dateFormat highlightCreationDate "YYYY-MM-DD hh:mm:ss A Z"}}
+- 📅 Highlight modified on:: {{dateFormat highlightModificationDate "YYYY-MM-DD hh:mm:ss A Z"}}
{{/each}}
`;
diff --git a/src/types.ts b/src/types.ts
index 88c9bcc..bcf6e5a 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -10,6 +10,9 @@ export interface IBook {
ZTITLE: string;
ZAUTHOR: string;
ZGENRE: string;
+ ZLANGUAGE: string;
+ ZLASTOPENDATE: number;
+ ZCOVERURL: string;
}
export interface IBookAnnotation {
@@ -18,6 +21,9 @@ export interface IBookAnnotation {
ZANNOTATIONREPRESENTATIVETEXT: string;
ZANNOTATIONSELECTEDTEXT: string;
ZANNOTATIONNOTE: string;
+ ZANNOTATIONCREATIONDATE: number;
+ ZANNOTATIONMODIFICATIONDATE: number;
+ ZANNOTATIONSTYLE: 0 | 1 | 2 | 3 | 4 | 5;
}
export interface Highlight {
@@ -30,5 +36,9 @@ export interface CombinedHighlight {
bookTitle: string;
bookId: string;
bookAuthor: string;
+ bookGenre: string;
+ bookLanguage: string;
+ bookLastOpenedDate: number;
+ bookCoverUrl: string;
annotations: Highlight[];
}
\ No newline at end of file
diff --git a/template-colors.png b/template-colors.png
new file mode 100644
index 0000000..bf9bace
Binary files /dev/null and b/template-colors.png differ
diff --git a/tsconfig.json b/tsconfig.json
index 7cd0e5e..3eea23a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,6 +11,7 @@
"importHelpers": true,
"isolatedModules": true,
"resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
"strictNullChecks": true,
"lib": [
"DOM",