Skip to content

Commit

Permalink
feat: add colored template for highlights. Add additional fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
bandantonio committed Mar 4, 2024
1 parent 2ed9fde commit fbab97a
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 10 deletions.
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,79 @@ 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:
- If you highlight a part of a sentence, the - `contextualText` will contain the whole sentence.
- 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:: <u>{{{highlight}}}</u>{{/if}}
{{#if (eq highlightStyle "1")}}- 🎯 Highlight:: <mark style="background:rgb(175,213,151); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "2")}}- 🎯 Highlight:: <mark style="background:rgb(181,205,238); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "3")}}- 🎯 Highlight:: <mark style="background:rgb(249,213,108); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "4")}}- 🎯 Highlight:: <mark style="background:rgb(242,178,188); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "5")}}- 🎯 Highlight:: <mark style="background:rgb(214,192,238); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
- 📝 Note:: {{#if note}}{{{note}}}{{else}}N/A{{/if}}
- <small>📅 Highlight taken on:: {{dateFormat highlightCreationDate "YYYY-MM-DD hh:mm:ss A Z"}}</small>
- <small>📅 Highlight modified on:: {{dateFormat highlightModificationDate "YYYY-MM-DD hh:mm:ss A Z"}}</small>
{{/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).
Expand Down
25 changes: 22 additions & 3 deletions main.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -66,7 +67,7 @@ export default class IBookHighlightsPlugin extends Plugin {
async getBooks(): Promise<IBook[]> {
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`;

Expand All @@ -85,7 +86,7 @@ export default class IBookHighlightsPlugin extends Plugin {
async getAnnotations(): Promise<IBookAnnotation[]> {
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`;
Expand Down Expand Up @@ -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
}
})
})
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
15 changes: 13 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down Expand Up @@ -38,7 +38,8 @@
"typescript": "4.7.4"
},
"dependencies": {
"dayjs": "^1.11.10",
"handlebars": "^4.7.8",
"sqlite3": "^5.1.7-rc.0"
}
}
}
14 changes: 13 additions & 1 deletion src/template.ts
Original file line number Diff line number Diff line change
@@ -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}}
Expand All @@ -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:: <u>{{{highlight}}}</u>{{/if}}
{{#if (eq highlightStyle "1")}}- 🎯 Highlight:: <mark style="background:rgb(175,213,151); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "2")}}- 🎯 Highlight:: <mark style="background:rgb(181,205,238); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "3")}}- 🎯 Highlight:: <mark style="background:rgb(249,213,108); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "4")}}- 🎯 Highlight:: <mark style="background:rgb(242,178,188); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
{{#if (eq highlightStyle "5")}}- 🎯 Highlight:: <mark style="background:rgb(214,192,238); color:#000; padding:2px;">{{{highlight}}}</mark>{{/if}}
- 📝 Note:: {{#if note}}{{{note}}}{{else}}N/A{{/if}}
- <small>📅 Highlight taken on:: {{dateFormat highlightCreationDate "YYYY-MM-DD hh:mm:ss A Z"}}</small>
- <small>📅 Highlight modified on:: {{dateFormat highlightModificationDate "YYYY-MM-DD hh:mm:ss A Z"}}</small>
{{/each}}
`;
Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export interface IBook {
ZTITLE: string;
ZAUTHOR: string;
ZGENRE: string;
ZLANGUAGE: string;
ZLASTOPENDATE: number;
ZCOVERURL: string;
}

export interface IBookAnnotation {
Expand All @@ -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 {
Expand All @@ -30,5 +36,9 @@ export interface CombinedHighlight {
bookTitle: string;
bookId: string;
bookAuthor: string;
bookGenre: string;
bookLanguage: string;
bookLastOpenedDate: number;
bookCoverUrl: string;
annotations: Highlight[];
}
Binary file added template-colors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"importHelpers": true,
"isolatedModules": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"strictNullChecks": true,
"lib": [
"DOM",
Expand Down

0 comments on commit fbab97a

Please sign in to comment.