-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 58e51e9
Showing
4 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
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,5 @@ | ||
# macOS | ||
.DS_Store | ||
|
||
# Don't include the generated pdfs | ||
out/* |
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,62 @@ | ||
# 📌 Notability Notes Converter 📌 | ||
|
||
This repository contains the necessary code to convert all of your notes to `.pdf` format. After running the script, all notes from the Notability app on your Mac will be exported as pdf to an `out` folder. | ||
|
||
### ⚠️ Requirements ⚠️ | ||
1. macOS | ||
2. [Notability.app](https://www.gingerlabs.com) for macOS | ||
|
||
## Running the script | ||
|
||
1. Append a pin emoji (📌) to each note file that you wan't to have exported. | ||
2. (Optional if editing notes from another Apple device) Wait for iCloud to sync. | ||
3. Then run from terminal | ||
|
||
``` | ||
$ osascript notability_pdf_export.scpt | ||
``` | ||
|
||
Or just run the file directly via Script Editor. | ||
|
||
### Example | ||
|
||
Structure of notes in Notability | ||
``` | ||
subject_1/note1📌.note | ||
subject_1/note2📌.note | ||
subject_1/note3📌.note | ||
subject_1/note4.note | ||
subject_2/example_note📌.note | ||
subject_3/private_note.note | ||
``` | ||
|
||
``` | ||
$ osascript notability_pdf_export.scpt | ||
Success | ||
$ | ||
``` | ||
|
||
After running the script a new directory containing all the required pdfs is created. | ||
|
||
``` | ||
# Structure of out folder | ||
out/subject_1/note1.pdf | ||
out/subject_1/note2.pdf | ||
out/subject_1/note3.pdf | ||
out/subject_2/example_note.pdf | ||
``` | ||
|
||
## Features | ||
|
||
* Creates a `.pdf` file for each note that ends with the pin emoji (📌) | ||
* Each pdf file will be correctly categorized by a folder that represents the Note subject | ||
* The script doesn't export the same note twice. (i.e. the pdf files are overwritten only when the modification time of the Notability note is greater than the pdfs that were generated beforehand) | ||
### Todo | ||
|
||
- [ ] Add flags for including the Paper 📜 / Page Margin 📄 in the pdf export settings. Currently each pdf is exported without the paper and page margins. | ||
- [ ] Add the option to flag (📌) an entire subject. | ||
- [ ] Add exclusion tag for notes that you don't want to be exported from tagged subjects. | ||
|
||
## License | ||
|
||
MIT |
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,31 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
from datetime import datetime, timedelta | ||
|
||
def arguments(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("datestring") | ||
return parser.parse_args() | ||
|
||
def create_expected_datestring(datestr): | ||
time_format = "%H:%M" | ||
date_format = "%d %b %Y" | ||
datetime_format = "{} {}".format(date_format, time_format) | ||
today = datetime.today() | ||
yesterday = today - timedelta(days=1) | ||
date_to_day_nr = lambda d: d.strftime(date_format) | ||
clean_datestr = datestr.replace( | ||
"at", "" | ||
).replace( | ||
"Today", date_to_day_nr(today) | ||
).replace( | ||
"Yesterday", date_to_day_nr(yesterday) | ||
) | ||
|
||
correct_datetime = datetime.strptime(clean_datestr, datetime_format) | ||
return correct_datetime.strftime("%A, %d %B %Y at %H:%M:%S") | ||
|
||
if __name__ == "__main__": | ||
args = arguments() | ||
print(create_expected_datestring(args.datestring)) |
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,137 @@ | ||
#!/usr/bin/osascript | ||
|
||
property exportFileExtension : ".pdf" | ||
property noteExportFlag : "📌" | ||
property notabilityName : "Notability" | ||
|
||
# Create the out folder | ||
tell application "Finder" | ||
set outFolder to my FilepathToThisFolderAsString() & "out" | ||
end tell | ||
|
||
# Launch Notability | ||
tell application notabilityName | ||
quit | ||
delay 1 | ||
launch | ||
delay 2 | ||
activate | ||
end tell | ||
|
||
tell application "System Events" | ||
my WaitUntilExists(window 1 of application process notabilityName) | ||
# Save notability main window for later | ||
set notabilityWindow to window 1 of application process notabilityName | ||
tell process notabilityName | ||
# This selects the All Notes tab | ||
select (row 1 of outline 1 of scroll area 2 of window 1) | ||
|
||
# For each note in All notes | ||
repeat with aRow in (every row of table 1 of scroll area 3 of notabilityWindow) | ||
repeat 1 times | ||
# Variables | ||
set currentNoteCategory to name of static text 1 of UI element 1 of aRow | ||
set currentNoteName to name of static text 2 of UI element 1 of aRow | ||
set currentNoteModDate to name of static text 3 of UI element of aRow | ||
set currentNoteModDate to my CreateDateFromDatestring(currentNoteModDate as text) | ||
|
||
# if current row contains export flag | ||
if (currentNoteName contains noteExportFlag) then | ||
# create a new name for the note without the export flag | ||
set noteNameWithoutEmoji to text 1 thru -2 of currentNoteName | ||
# create the out filename for our note | ||
set outNoteFilename to noteNameWithoutEmoji & exportFileExtension | ||
set outFolder to outFolder & "/" & currentNoteCategory | ||
set outNoteFilepath to outFolder & "/" & outNoteFilename | ||
# create dir if needed | ||
do shell script "mkdir -p " & quoted form of outFolder | ||
|
||
|
||
# check if note already exists | ||
set noteFileExists to my FileExists(outNoteFilepath) | ||
if noteFileExists then | ||
# check if the current date is newer | ||
tell application "System Events" to set lastLocalModDate to modification date of file outNoteFilepath | ||
if lastLocalModDate ≥ currentNoteModDate then | ||
# continue the loop, we don't have to export this | ||
exit repeat -- continue | ||
end if | ||
end if | ||
|
||
# select it, so the export knows what to export | ||
select aRow | ||
|
||
# export | ||
click menu item "PDF..." of menu 1 of menu item "Export As" of menu 1 of menu bar item "File" of menu bar 1 | ||
|
||
set exportDialogWindow to window "Export" | ||
my WaitUntilExists(exportDialogWindow) | ||
|
||
# handle Export dialog | ||
tell (exportDialogWindow) | ||
# set focus on the text field | ||
set focused of text field 1 to true | ||
|
||
# Change the output folder | ||
keystroke "g" using {command down, shift down} | ||
delay 0.1 | ||
my WaitUntilExists(sheet 1) | ||
tell sheet 1 | ||
set value of combo box 1 to outFolder | ||
click button "Go" | ||
end tell | ||
|
||
# set the new filename without emojis | ||
set value of text field 1 to outNoteFilename | ||
|
||
# we don't want page margins or the paper to be included in the final pdf (uncheck all checkboxes) | ||
repeat with aCheckbox in (every checkbox) | ||
tell aCheckbox to if value is 1 then click | ||
end repeat | ||
|
||
# finally, export | ||
click button "Export" | ||
|
||
# if the file exists | ||
if noteFileExists then | ||
# wait for the action sheet | ||
my WaitUntilExists(sheet 1) | ||
# click the button | ||
click button "Replace" of sheet 1 | ||
end if | ||
end tell | ||
end if | ||
end repeat | ||
end repeat | ||
end tell | ||
end tell | ||
|
||
tell application notabilityName to quit | ||
|
||
return "Success" | ||
|
||
|
||
# Sub-routines | ||
on FileExists(theFile) -- (String) as Boolean | ||
tell application "System Events" | ||
return (exists file theFile) | ||
end tell | ||
end FileExists | ||
|
||
on CreateDateFromDatestring(theString) | ||
return date (do shell script "python3 " & my FilepathToThisFolderAsString() & "date_converter.py " & quoted form of theString) | ||
end CreateDateFromDatestring | ||
|
||
on FilepathToThisFolderAsString() | ||
tell application "Finder" | ||
return POSIX path of (parent of (path to me) as string) | ||
end tell | ||
end FilepathToThisFolderAsString | ||
|
||
on WaitUntilExists(theElement) | ||
tell current application | ||
repeat until (exists theElement) | ||
delay 1 | ||
end repeat | ||
end tell | ||
end WaitUntilExists |