├── .gitattributes ├── .gitignore ├── .tags ├── .tags1 ├── LICENSE ├── README.md ├── alfred-workflow ├── PDF to Skim notes.alfredworkflow └── Skim to PDF notes.alfredworkflow ├── img ├── example-acrobat.png ├── example-skim.png ├── pdf-icon-01.png ├── pdf-icon-02.png ├── pdf-icon-03.png ├── pdf-icon-04.png └── skim-icon.png ├── releases └── SkimPDF-v1.1.zip ├── scr ├── skim_pdf.py ├── skim_pdf_to_pdf_automator.py └── skim_pdf_to_skim_automator.py ├── src-osx-automator ├── Convert to pdf notes.workflow │ └── Contents │ │ ├── Info.plist │ │ ├── QuickLook │ │ ├── Preview.png │ │ └── Thumbnail.png │ │ └── document.wflow └── Convert to skim notes.workflow │ └── Contents │ ├── Info.plist │ ├── QuickLook │ ├── Preview.png │ └── Thumbnail.png │ └── document.wflow └── test ├── test copy ├── test.pdf └── test_embedded.pdf ├── test.pdf └── test_embedded.pdf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test/ 2 | .tags 3 | .tags1 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.tags: -------------------------------------------------------------------------------- 1 | SkimPDF /Users/Alex/Documents/Dev/active/skim-pdf/README.md /^# SkimPDF$/;" function line:1 2 | Methods /Users/Alex/Documents/Dev/active/skim-pdf/README.md /^## Methods$/;" function line:17 3 | Batch processing /Users/Alex/Documents/Dev/active/skim-pdf/README.md /^## Batch processing$/;" function line:23 4 | Available options /Users/Alex/Documents/Dev/active/skim-pdf/README.md /^## Available options$/;" function line:27 5 | Alfred Workflows /Users/Alex/Documents/Dev/active/skim-pdf/README.md /^## Alfred Workflows$/;" function line:32 6 | system /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 7 | walk /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 8 | path /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 9 | SkimPDF /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^class SkimPDF(object):$/;" class line:14 10 | __init__ /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def __init__(self):$/;" member line:16 class:SkimPDF 11 | convert_to_pdf_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def convert_to_pdf_notes(self, in_pdf):$/;" member line:23 class:SkimPDF 12 | batch_convert_to_pdf_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def batch_convert_to_pdf_notes(self, folder):$/;" member line:43 class:SkimPDF 13 | convert_to_skim_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def convert_to_skim_notes(self, in_pdf):$/;" member line:62 class:SkimPDF 14 | batch_convert_to_skim_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def batch_convert_to_skim_notes(self, folder):$/;" member line:82 class:SkimPDF 15 | report /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def report(self, messages):$/;" member line:101 class:SkimPDF 16 | skim /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^skim = SkimPDF()$/;" variable line:111 17 | -------------------------------------------------------------------------------- /.tags1: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ 2 | !_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/ 3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ 4 | !_TAG_PROGRAM_NAME Exuberant Ctags // 5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ 6 | !_TAG_PROGRAM_VERSION 5.8 // 7 | system /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 8 | walk /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 9 | path /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^from os import system, walk, path$/;" namespace line:11 10 | SkimPDF /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^class SkimPDF(object):$/;" class line:14 11 | __init__ /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def __init__(self):$/;" member line:16 class:SkimPDF 12 | convert_to_pdf_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def convert_to_pdf_notes(self, in_pdf):$/;" member line:23 class:SkimPDF 13 | batch_convert_to_pdf_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def batch_convert_to_pdf_notes(self, folder):$/;" member line:43 class:SkimPDF 14 | convert_to_skim_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def convert_to_skim_notes(self, in_pdf):$/;" member line:62 class:SkimPDF 15 | batch_convert_to_skim_notes /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def batch_convert_to_skim_notes(self, folder):$/;" member line:82 class:SkimPDF 16 | report /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^ def report(self, messages):$/;" member line:101 class:SkimPDF 17 | skim /Users/Alex/Documents/Dev/active/skim-pdf/scr/skim_pdf.py /^skim = SkimPDF()$/;" variable line:111 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 alexandergogl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SkimPDF 2 | 3 | SkimPDF is a Python wrapper for the CLI `skimpdf` of [Skim](https://skim-app.sourceforge.io/). The wrapper can be used to integrate skimpdf in a larger Python workflow. Below are two examples for OSX-Automator and Alfred. 4 | 5 | Skim is a PDF viewer with great search and annotation tools for OSX. It stores annotations in a non-standard format, thus the annotation can not viewed or edited in other PDF viewer like Adobe Acrobat Reader. However, Skim can convert Skim notes to standard PDF notes (embed) or make PDF notes editable in Skim (unembed). Embedding and unembedding can be done inside of Skim. 6 | 7 | ![](img/example-skim.png) 8 | PDF viewed in Skim with Skim annotations. 9 | 10 | ![](img/example-acrobat.png) 11 | The same PDF with embedded annotations viewed in Adobe Acrobat Reader DC. 12 | 13 | ## How it works 14 | 15 | The Python class `SkimPDF` builds on `skimpdf` to automate the conversion step: 16 | 17 | 1. Embed notes 18 | 2. Unembed notes 19 | 3. Batch embed and unembed notes (works with nested folders) 20 | 21 | I have used the script to embed Skim notes of 568 pdfs scattered in a folder with various subfolders. It took about 5 minutes. Be aware, that the script won't process files with a `"` in its filepath and that the files are overwritten, so make a copy before running on large sets of files. 22 | 23 | ## How to install and use it 24 | 25 | There are three options how to use SkimPDF: 26 | 27 | 1. as an OSX automator workflow 28 | 2. as an Alfred Workflow, or 29 | 3. as a Python module 30 | 31 | ### OSX-Automator 32 | 33 | For ease of use, I have wrapped the python script in the OSX Automator workflows `Convert to pdf notes.workflow` and `Convert to skim notes.workflow` to process one or more selected PDFs. The script detects if one PDF or multiple PDFs or folders have been selected and automatically batch processes it. 34 | 35 | The workflows process a selected PDF file, or multiple PDFs, folders, and nested folders (batch processing). Non-PDF files are ignored. **WARNING:** The workflows replaces the selected files. 36 | 37 | Install the workflow as an OSX service by: 38 | 39 | 1. download the SkimPDF Automator Workflows [here](https://github.com/alexandergogl/SkimPDF/releases/latest) 40 | 2. double-clicking on the donwloaded files `Convert to pdf notes.workflow` and `Convert to skim notes.workflow` and select "Install as service." 41 | 42 | Start the workflow by 43 | 44 | 1. selecting PDF files or folders, 45 | 2. click right, 46 | 3. navigate to `services` (German: Dienste) > `PDF - Skim => PDF notes` or `PDF - PDF => Skim notes` 47 | 48 | ### Alfred Workflows 49 | 50 | For ease of use, I have wrapped the python script in the [Alfred Workflows](https://www.alfredapp.com/) `PDF to Skim notes.alfredworkflow` and `Skim to PDF notes.alfredworkflow` to process one or more selected PDFs. 51 | 52 | The workflows process a selected PDF file, or multiple PDFs, folders, and nested folders (batch processing). Non-PDF files are ignored. **WARNING:** The workflows overwrite the selected files. 53 | 54 | Install the workflow as an Alfred workflow by: 55 | 56 | 1. download the Alfred Workflows [here](https://github.com/alexandergogl/SkimPDF/releases/latest) 57 | 2. double-clicking on the donwloaded files `PDF to Skim notes.alfredworkflow` and `Skim to PDF notes.alfredworkflow`. Be aware, that you need an active Alfred power user licence to enable custom workflows. 58 | 59 | ### Python module 60 | 61 | If you need to have more control on the script like making a copy of the converted pdf instead of overwriting it, then you can access the Python class options by loading class as a module in a python script or via CLI. 62 | 63 | Download the module from `src/skim_pdf.py` or [here](https://github.com/alexandergogl/SkimPDF/releases/latest) (Source code) 64 | 65 | #### Available options 66 | 67 | ``` 68 | skim = SkimPDF() 69 | 70 | # Path to skimpdf 71 | skim.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 72 | 73 | # Replace pdf or place a copy in place 74 | skim.replace_original = True 75 | 76 | # If skim.replace_original is set to False, 77 | # then you can set the embed or unembed suffix 78 | skim.embed_suffix = '_embedded' 79 | skim.unembed_suffix = '_skim_notes' 80 | ``` 81 | 82 | #### Available methods 83 | 84 | ``` 85 | # Convert Skim notes to PDF notes (embed) 86 | skim.convert_to_pdf_notes('../path/to/pdf file.pdf') 87 | 88 | # Convert PDF notes to Skim notes (unembed) 89 | skim.convert_to_skim_notes('../path/to/pdf file.pdf') 90 | 91 | # Batch convert notes in a folder 92 | skim.batch_convert_to_pdf_notes('../path/to/Literature folder') 93 | skim.batch_convert_to_skim_notes('../path/to/Literature folder') 94 | ``` 95 | -------------------------------------------------------------------------------- /alfred-workflow/PDF to Skim notes.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/alfred-workflow/PDF to Skim notes.alfredworkflow -------------------------------------------------------------------------------- /alfred-workflow/Skim to PDF notes.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/alfred-workflow/Skim to PDF notes.alfredworkflow -------------------------------------------------------------------------------- /img/example-acrobat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/example-acrobat.png -------------------------------------------------------------------------------- /img/example-skim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/example-skim.png -------------------------------------------------------------------------------- /img/pdf-icon-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/pdf-icon-01.png -------------------------------------------------------------------------------- /img/pdf-icon-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/pdf-icon-02.png -------------------------------------------------------------------------------- /img/pdf-icon-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/pdf-icon-03.png -------------------------------------------------------------------------------- /img/pdf-icon-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/pdf-icon-04.png -------------------------------------------------------------------------------- /img/skim-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/img/skim-icon.png -------------------------------------------------------------------------------- /releases/SkimPDF-v1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/releases/SkimPDF-v1.1.zip -------------------------------------------------------------------------------- /scr/skim_pdf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | skim_pdf. 4 | 5 | Embed Skim notes as PDF notes or convert PDF notes to Skim notes. 6 | Date: 2018-12-18 7 | Version: 1.1 8 | Author: Alexander Gogl 9 | """ 10 | 11 | from os import system, walk, path 12 | 13 | 14 | class SkimPDF(object): 15 | """docstring for SkimPDF.""" 16 | def __init__(self): 17 | self.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 18 | self.embed_suffix = '_embedded' 19 | self.unembed_suffix = '_skim_notes' 20 | self.replace_original = True 21 | pass 22 | 23 | def convert_to_pdf_notes(self, in_pdf): 24 | """Embed skim notes to PDF notes.""" 25 | if self.replace_original is False: 26 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.embed_suffix) 27 | else: 28 | out_pdf = in_pdf 29 | 30 | # Embed notes 31 | cmd = '%s embed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 32 | 33 | result = system(cmd) 34 | 35 | # Compose message 36 | if result == 0: 37 | message = "Embeded notes to '%s'" % out_pdf 38 | else: 39 | message = result 40 | 41 | return message 42 | 43 | def batch_convert_to_pdf_notes(self, folder): 44 | """Loop through directories in given folder and embed notes.""" 45 | messages = [] 46 | i = 0 47 | for path, subdirs, files in walk(folder): 48 | for name in files: 49 | if name.endswith(".pdf"): 50 | i += 1 51 | # embed notes to pdf 52 | pdf_file = "%s/%s" % (path, name) 53 | result = skim.convert_to_pdf_notes(pdf_file) 54 | # add result message to report 55 | messages.append(result) 56 | # report current state 57 | print(i) 58 | 59 | self.report(messages) 60 | pass 61 | 62 | def convert_to_skim_notes(self, in_pdf): 63 | """Convert PDF notes to Skim notes (unembed).""" 64 | if self.replace_original is False: 65 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.skim_suffix) 66 | else: 67 | out_pdf = in_pdf 68 | 69 | # Convert PDF notes to Skim notes 70 | cmd = '%s unembed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 71 | 72 | result = system(cmd) 73 | 74 | # Compose message 75 | if result == 0: 76 | message = "Converted PDF notes to Skim notes in '%s'" % out_pdf 77 | else: 78 | message = result 79 | 80 | return message 81 | 82 | def batch_convert_to_skim_notes(self, folder): 83 | """Loop through directories in given folder and embed notes.""" 84 | messages = [] 85 | i = 0 86 | for path, subdirs, files in walk(folder): 87 | for name in files: 88 | if name.endswith(".pdf"): 89 | i += 1 90 | # embed notes to pdf 91 | pdf_file = "%s/%s" % (path, name) 92 | result = skim.convert_to_skim_notes(pdf_file) 93 | # add result message to report 94 | messages.append(result) 95 | # report current state 96 | print(i) 97 | 98 | self.report(messages) 99 | pass 100 | 101 | def report(self, messages): 102 | """Print list of processed pdfs.""" 103 | print("\n\nProcessing PDFs done:") 104 | 105 | for i in range(len(messages)): 106 | message = "%s: %s" % (i + 1, messages[i]) 107 | print(message) 108 | pass 109 | 110 | 111 | skim = SkimPDF() 112 | skim.replace_original = False 113 | 114 | skim.embed_notes('../test/test.pdf') 115 | # skim.convert_to_skim_notes('../test/test.pdf') 116 | 117 | # batch embeding process with path to folder with literature 118 | # skim.batch_convert_to_pdf_notes('../test') 119 | -------------------------------------------------------------------------------- /scr/skim_pdf_to_pdf_automator.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | skim_pdf. 4 | 5 | Embed Skim notes as PDF notes or convert PDF notes to Skim notes. 6 | Date: 2019-01-30 7 | Version: 1.2 8 | Author: Alexander Gogl 9 | """ 10 | 11 | import sys 12 | import os 13 | # import system, walk, path, argv 14 | 15 | 16 | class SkimPDF(object): 17 | """docstring for SkimPDF.""" 18 | def __init__(self): 19 | self.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 20 | self.embed_suffix = '_embedded' 21 | self.unembed_suffix = '_skim_notes' 22 | self.replace_original = True 23 | pass 24 | 25 | def convert_to_pdf_notes(self, in_pdf): 26 | """Embed skim notes to PDF notes.""" 27 | if self.replace_original is False: 28 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.embed_suffix) 29 | else: 30 | out_pdf = in_pdf 31 | 32 | # Embed notes 33 | cmd = '%s embed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 34 | 35 | os.system(cmd) 36 | pass 37 | 38 | def batch_convert_to_pdf_notes(self, folder): 39 | """Loop through directories in given folder and embed notes.""" 40 | messages = [] 41 | i = 0 42 | for path, subdirs, files in os.walk(folder): 43 | for name in files: 44 | if name.endswith(".pdf"): 45 | i += 1 46 | # embed notes to pdf 47 | pdf_file = "%s/%s" % (path, name) 48 | skim.convert_to_pdf_notes(pdf_file) 49 | 50 | return i 51 | 52 | def convert_to_skim_notes(self, in_pdf): 53 | """Convert PDF notes to Skim notes (unembed).""" 54 | if self.replace_original is False: 55 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.skim_suffix) 56 | else: 57 | out_pdf = in_pdf 58 | 59 | # Convert PDF notes to Skim notes 60 | cmd = '%s unembed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 61 | 62 | os.system(cmd) 63 | pass 64 | 65 | def batch_convert_to_skim_notes(self, folder): 66 | """Loop through directories in given folder and embed notes.""" 67 | messages = [] 68 | i = 0 69 | for path, subdirs, files in os.walk(folder): 70 | for name in files: 71 | if name.endswith(".pdf"): 72 | i += 1 73 | # embed notes to pdf 74 | pdf_file = "%s/%s" % (path, name) 75 | skim.convert_to_skim_notes(pdf_file) 76 | 77 | return i 78 | 79 | 80 | skim = SkimPDF() 81 | skim.replace_original = True 82 | 83 | paths = sys.argv[1:] 84 | 85 | if len(paths) > 1: 86 | # Multiple elements selected 87 | i = 0 88 | for path in paths: 89 | if os.path.isdir(path): 90 | i += skim.batch_convert_to_pdf_notes(path) 91 | else: 92 | skim.convert_to_pdf_notes(path) 93 | i += 1 94 | else: 95 | # one element selected 96 | path = paths[0] 97 | if os.path.isdir(path): 98 | i = skim.batch_convert_to_pdf_notes(path) 99 | else: 100 | skim.convert_to_pdf_notes(path) 101 | i = 1 102 | 103 | message = 'Converted %s files with skim notes to pdf notes' % i 104 | print(message) 105 | -------------------------------------------------------------------------------- /scr/skim_pdf_to_skim_automator.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | skim_pdf. 4 | 5 | Embed Skim notes as PDF notes or convert PDF notes to Skim notes. 6 | Date: 2019-01-30 7 | Version: 1.2 8 | Author: Alexander Gogl 9 | """ 10 | 11 | import sys 12 | import os 13 | # import system, walk, path, argv 14 | 15 | 16 | class SkimPDF(object): 17 | """docstring for SkimPDF.""" 18 | def __init__(self): 19 | self.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 20 | self.embed_suffix = '_embedded' 21 | self.unembed_suffix = '_skim_notes' 22 | self.replace_original = True 23 | pass 24 | 25 | def convert_to_pdf_notes(self, in_pdf): 26 | """Embed skim notes to PDF notes.""" 27 | if self.replace_original is False: 28 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.embed_suffix) 29 | else: 30 | out_pdf = in_pdf 31 | 32 | # Embed notes 33 | cmd = '%s embed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 34 | 35 | os.system(cmd) 36 | pass 37 | 38 | def batch_convert_to_pdf_notes(self, folder): 39 | """Loop through directories in given folder and embed notes.""" 40 | messages = [] 41 | i = 0 42 | for path, subdirs, files in os.walk(folder): 43 | for name in files: 44 | if name.endswith(".pdf"): 45 | i += 1 46 | # embed notes to pdf 47 | pdf_file = "%s/%s" % (path, name) 48 | skim.convert_to_pdf_notes(pdf_file) 49 | 50 | return i 51 | 52 | def convert_to_skim_notes(self, in_pdf): 53 | """Convert PDF notes to Skim notes (unembed).""" 54 | if self.replace_original is False: 55 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.skim_suffix) 56 | else: 57 | out_pdf = in_pdf 58 | 59 | # Convert PDF notes to Skim notes 60 | cmd = '%s unembed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 61 | 62 | os.system(cmd) 63 | pass 64 | 65 | def batch_convert_to_skim_notes(self, folder): 66 | """Loop through directories in given folder and embed notes.""" 67 | messages = [] 68 | i = 0 69 | for path, subdirs, files in os.walk(folder): 70 | for name in files: 71 | if name.endswith(".pdf"): 72 | i += 1 73 | # embed notes to pdf 74 | pdf_file = "%s/%s" % (path, name) 75 | skim.convert_to_skim_notes(pdf_file) 76 | 77 | return i 78 | 79 | 80 | skim = SkimPDF() 81 | skim.replace_original = True 82 | 83 | paths = sys.argv[1:] 84 | 85 | if len(paths) > 1: 86 | # Multiple elements selected 87 | i = 0 88 | for path in paths: 89 | if os.path.isdir(path): 90 | i += skim.batch_convert_to_skim_notes(path) 91 | else: 92 | skim.convert_to_skim_notes(path) 93 | i += 1 94 | else: 95 | # one element selected 96 | path = paths[0] 97 | if os.path.isdir(path): 98 | i = skim.batch_convert_to_skim_notes(path) 99 | else: 100 | skim.convert_to_skim_notes(path) 101 | i = 1 102 | 103 | message = 'Converted %s files with pdf notes to skim notes' % i 104 | print(message) 105 | -------------------------------------------------------------------------------- /src-osx-automator/Convert to pdf notes.workflow/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSServices 6 | 7 | 8 | NSBackgroundColorName 9 | background 10 | NSIconName 11 | NSActionTemplate 12 | NSMenuItem 13 | 14 | default 15 | Convert to pdf notes 16 | 17 | NSMessage 18 | runWorkflowAsService 19 | NSSendFileTypes 20 | 21 | public.item 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src-osx-automator/Convert to pdf notes.workflow/Contents/QuickLook/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/src-osx-automator/Convert to pdf notes.workflow/Contents/QuickLook/Preview.png -------------------------------------------------------------------------------- /src-osx-automator/Convert to pdf notes.workflow/Contents/QuickLook/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/src-osx-automator/Convert to pdf notes.workflow/Contents/QuickLook/Thumbnail.png -------------------------------------------------------------------------------- /src-osx-automator/Convert to pdf notes.workflow/Contents/document.wflow: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AMApplicationBuild 6 | 444.39 7 | AMApplicationVersion 8 | 2.9 9 | AMDocumentVersion 10 | 2 11 | actions 12 | 13 | 14 | action 15 | 16 | AMAccepts 17 | 18 | Container 19 | List 20 | Optional 21 | 22 | Types 23 | 24 | com.apple.cocoa.path 25 | 26 | 27 | AMActionVersion 28 | 2.1.1 29 | AMApplication 30 | 31 | Finder 32 | 33 | AMParameterProperties 34 | 35 | AMProvides 36 | 37 | Container 38 | List 39 | Types 40 | 41 | com.apple.cocoa.path 42 | 43 | 44 | AMRequiredResources 45 | 46 | ActionBundlePath 47 | /System/Library/Automator/Get Selected Finder Items 2.action 48 | ActionName 49 | Ausgewählte Finder-Objekte abfragen 50 | ActionParameters 51 | 52 | BundleIdentifier 53 | com.apple.Automator.GetSelectedFinderItems2 54 | CFBundleVersion 55 | 2.1.1 56 | CanShowSelectedItemsWhenRun 57 | 58 | CanShowWhenRun 59 | 60 | Category 61 | 62 | AMCategoryFilesAndFolders 63 | 64 | Class Name 65 | AMGetSelectedFinderItemsAction 66 | InputUUID 67 | 143E0C3E-2CB9-4064-A23D-21752BFB6CDC 68 | Keywords 69 | 70 | OutputUUID 71 | 4C12FD8E-2220-4209-9465-D97281574CFC 72 | UUID 73 | F56381A4-BBE3-4B25-8C03-98A17327E566 74 | UnlocalizedApplications 75 | 76 | Finder 77 | 78 | arguments 79 | 80 | 81 | 82 | 83 | action 84 | 85 | AMAccepts 86 | 87 | Container 88 | List 89 | Optional 90 | 91 | Types 92 | 93 | com.apple.cocoa.string 94 | 95 | 96 | AMActionVersion 97 | 2.0.3 98 | AMApplication 99 | 100 | Automator 101 | 102 | AMParameterProperties 103 | 104 | COMMAND_STRING 105 | 106 | CheckedForUserDefaultShell 107 | 108 | inputMethod 109 | 110 | shell 111 | 112 | source 113 | 114 | 115 | AMProvides 116 | 117 | Container 118 | List 119 | Types 120 | 121 | com.apple.cocoa.string 122 | 123 | 124 | ActionBundlePath 125 | /System/Library/Automator/Run Shell Script.action 126 | ActionName 127 | Shell-Skript ausführen 128 | ActionParameters 129 | 130 | COMMAND_STRING 131 | # -*- coding: utf-8 -*- 132 | """ 133 | skim_pdf. 134 | 135 | Embed Skim notes as PDF notes or convert PDF notes to Skim notes. 136 | Date: 2019-01-30 137 | Version: 1.2 138 | Author: Alexander Gogl 139 | """ 140 | 141 | import sys 142 | import os 143 | # import system, walk, path, argv 144 | 145 | 146 | class SkimPDF(object): 147 | """docstring for SkimPDF.""" 148 | def __init__(self): 149 | self.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 150 | self.embed_suffix = '_embedded' 151 | self.unembed_suffix = '_skim_notes' 152 | self.replace_original = True 153 | pass 154 | 155 | def convert_to_pdf_notes(self, in_pdf): 156 | """Embed skim notes to PDF notes.""" 157 | if self.replace_original is False: 158 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.embed_suffix) 159 | else: 160 | out_pdf = in_pdf 161 | 162 | # Embed notes 163 | cmd = '%s embed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 164 | 165 | os.system(cmd) 166 | pass 167 | 168 | def batch_convert_to_pdf_notes(self, folder): 169 | """Loop through directories in given folder and embed notes.""" 170 | messages = [] 171 | i = 0 172 | for path, subdirs, files in os.walk(folder): 173 | for name in files: 174 | if name.endswith(".pdf"): 175 | i += 1 176 | # embed notes to pdf 177 | pdf_file = "%s/%s" % (path, name) 178 | skim.convert_to_pdf_notes(pdf_file) 179 | 180 | return i 181 | 182 | def convert_to_skim_notes(self, in_pdf): 183 | """Convert PDF notes to Skim notes (unembed).""" 184 | if self.replace_original is False: 185 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.skim_suffix) 186 | else: 187 | out_pdf = in_pdf 188 | 189 | # Convert PDF notes to Skim notes 190 | cmd = '%s unembed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 191 | 192 | os.system(cmd) 193 | pass 194 | 195 | def batch_convert_to_skim_notes(self, folder): 196 | """Loop through directories in given folder and embed notes.""" 197 | messages = [] 198 | i = 0 199 | for path, subdirs, files in os.walk(folder): 200 | for name in files: 201 | if name.endswith(".pdf"): 202 | i += 1 203 | # embed notes to pdf 204 | pdf_file = "%s/%s" % (path, name) 205 | skim.convert_to_skim_notes(pdf_file) 206 | 207 | return i 208 | 209 | 210 | skim = SkimPDF() 211 | skim.replace_original = True 212 | 213 | paths = sys.argv[1:] 214 | 215 | if len(paths) > 1: 216 | # Multiple elements selected 217 | i = 0 218 | for path in paths: 219 | if os.path.isdir(path): 220 | i += skim.batch_convert_to_pdf_notes(path) 221 | else: 222 | skim.convert_to_pdf_notes(path) 223 | i += 1 224 | else: 225 | # one element selected 226 | path = paths[0] 227 | if os.path.isdir(path): 228 | i = skim.batch_convert_to_pdf_notes(path) 229 | else: 230 | skim.convert_to_pdf_notes(path) 231 | i = 1 232 | 233 | message = 'Converted %s files with skim notes to pdf notes' % i 234 | print(message) 235 | 236 | CheckedForUserDefaultShell 237 | 238 | inputMethod 239 | 1 240 | shell 241 | /usr/bin/python 242 | source 243 | 244 | 245 | BundleIdentifier 246 | com.apple.RunShellScript 247 | CFBundleVersion 248 | 2.0.3 249 | CanShowSelectedItemsWhenRun 250 | 251 | CanShowWhenRun 252 | 253 | Category 254 | 255 | AMCategoryUtilities 256 | 257 | Class Name 258 | RunShellScriptAction 259 | InputUUID 260 | ADBA5407-4223-4BC4-A5B9-9F6EDEBC0DE1 261 | Keywords 262 | 263 | Shell 264 | Skript 265 | Befehl 266 | Ausführen 267 | Unix 268 | 269 | OutputUUID 270 | A778BDB9-D6B4-4EDD-AFB6-010FAA6824E7 271 | UUID 272 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 273 | UnlocalizedApplications 274 | 275 | Automator 276 | 277 | arguments 278 | 279 | 0 280 | 281 | default value 282 | 0 283 | name 284 | inputMethod 285 | required 286 | 0 287 | type 288 | 0 289 | uuid 290 | 0 291 | 292 | 1 293 | 294 | default value 295 | 296 | name 297 | source 298 | required 299 | 0 300 | type 301 | 0 302 | uuid 303 | 1 304 | 305 | 2 306 | 307 | default value 308 | 309 | name 310 | CheckedForUserDefaultShell 311 | required 312 | 0 313 | type 314 | 0 315 | uuid 316 | 2 317 | 318 | 3 319 | 320 | default value 321 | 322 | name 323 | COMMAND_STRING 324 | required 325 | 0 326 | type 327 | 0 328 | uuid 329 | 3 330 | 331 | 4 332 | 333 | default value 334 | /bin/sh 335 | name 336 | shell 337 | required 338 | 0 339 | type 340 | 0 341 | uuid 342 | 4 343 | 344 | 345 | isViewVisible 346 | 347 | location 348 | 550.000000:370.000000 349 | nibPath 350 | /System/Library/Automator/Run Shell Script.action/Contents/Resources/Base.lproj/main.nib 351 | 352 | isViewVisible 353 | 354 | 355 | 356 | action 357 | 358 | AMAccepts 359 | 360 | Container 361 | List 362 | Optional 363 | 364 | Types 365 | 366 | * 367 | 368 | 369 | AMActionVersion 370 | v.1.0.2 371 | AMApplication 372 | 373 | Automator 374 | 375 | AMParameterProperties 376 | 377 | variableUUID 378 | 379 | isPathPopUp 380 | 381 | selectedVariableUUID 382 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 383 | 384 | 385 | AMProvides 386 | 387 | Container 388 | List 389 | Types 390 | 391 | * 392 | 393 | 394 | AMRequiredResources 395 | 396 | ActionBundlePath 397 | /System/Library/Automator/Set Value of Variable.action 398 | ActionName 399 | Wert der Variablen festlegen 400 | ActionParameters 401 | 402 | variableUUID 403 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 404 | 405 | BundleIdentifier 406 | com.apple.Automator.SetValueofVariable 407 | CFBundleVersion 408 | 1.0.2 409 | CanShowSelectedItemsWhenRun 410 | 411 | CanShowWhenRun 412 | 413 | Category 414 | 415 | AMCategoryUtilities 416 | 417 | Class Name 418 | Set_Value_of_Variable 419 | InputUUID 420 | B49A8830-5941-4E83-958C-896E92CDBFE4 421 | Keywords 422 | 423 | Variable 424 | Einbinden 425 | Eingabe 426 | Ausgabe 427 | Speicher 428 | 429 | OutputUUID 430 | 8F3A164B-7F71-40DD-B123-BAD5DC9BDA81 431 | UUID 432 | B698066D-B9AA-4959-A92F-B29D59FE0079 433 | UnlocalizedApplications 434 | 435 | Automator 436 | 437 | arguments 438 | 439 | 0 440 | 441 | default value 442 | 443 | name 444 | variableUUID 445 | required 446 | 0 447 | type 448 | 0 449 | uuid 450 | 0 451 | 452 | 453 | isViewVisible 454 | 455 | location 456 | 550.000000:475.000000 457 | nibPath 458 | /System/Library/Automator/Set Value of Variable.action/Contents/Resources/Base.lproj/main.nib 459 | 460 | isViewVisible 461 | 462 | 463 | 464 | action 465 | 466 | AMAccepts 467 | 468 | Container 469 | List 470 | Optional 471 | 472 | Types 473 | 474 | 475 | AMActionVersion 476 | v.1.0 477 | AMApplication 478 | 479 | Automator 480 | 481 | AMParameterProperties 482 | 483 | message 484 | 485 | tokenizedValue 486 | 487 | $(FFB71E96-5A84-4341-A19C-750EC1CC09BD) 488 | 489 | 490 | subtitle 491 | 492 | title 493 | 494 | tokenizedValue 495 | 496 | Convert to skim notes 497 | 498 | 499 | 500 | AMProvides 501 | 502 | Container 503 | List 504 | Types 505 | 506 | 507 | ActionBundlePath 508 | /System/Library/Automator/Display Notification.action 509 | ActionName 510 | Mitteilungen anzeigen 511 | ActionParameters 512 | 513 | message 514 | $(FFB71E96-5A84-4341-A19C-750EC1CC09BD) 515 | subtitle 516 | 517 | title 518 | Convert to skim notes 519 | 520 | BundleIdentifier 521 | com.apple.Automator.Display-Notification 522 | CFBundleVersion 523 | 1.0 524 | CanShowSelectedItemsWhenRun 525 | 526 | CanShowWhenRun 527 | 528 | Category 529 | 530 | AMCategoryUtilities 531 | 532 | Class Name 533 | AMDisplayNotificationAction 534 | IgnoresInput 535 | 536 | InputUUID 537 | EB224DE4-E74B-4168-BF96-740EA509F79A 538 | Keywords 539 | 540 | OutputUUID 541 | 8DA7DAFA-5F16-4F92-9FB4-D57D23A7ECDA 542 | UUID 543 | F9A4A8A2-33F6-452A-BE58-8EF6A996339B 544 | UnlocalizedApplications 545 | 546 | Automator 547 | 548 | arguments 549 | 550 | 0 551 | 552 | default value 553 | 554 | name 555 | subtitle 556 | required 557 | 0 558 | type 559 | 0 560 | uuid 561 | 0 562 | 563 | 1 564 | 565 | default value 566 | 567 | name 568 | title 569 | required 570 | 0 571 | type 572 | 0 573 | uuid 574 | 1 575 | 576 | 2 577 | 578 | default value 579 | 580 | name 581 | message 582 | required 583 | 0 584 | type 585 | 0 586 | uuid 587 | 2 588 | 589 | 590 | isViewVisible 591 | 592 | location 593 | 550.000000:664.000000 594 | nibPath 595 | /System/Library/Automator/Display Notification.action/Contents/Resources/Base.lproj/main.nib 596 | 597 | isViewVisible 598 | 599 | 600 | 601 | connectors 602 | 603 | 0B53E290-2300-42B8-B57B-8D309759951E 604 | 605 | from 606 | B698066D-B9AA-4959-A92F-B29D59FE0079 - B698066D-B9AA-4959-A92F-B29D59FE0079 607 | to 608 | F9A4A8A2-33F6-452A-BE58-8EF6A996339B - F9A4A8A2-33F6-452A-BE58-8EF6A996339B 609 | 610 | 24E8E501-42C7-47AA-90FF-65E2779D49D1 611 | 612 | from 613 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 - BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 614 | to 615 | B698066D-B9AA-4959-A92F-B29D59FE0079 - B698066D-B9AA-4959-A92F-B29D59FE0079 616 | 617 | 72107071-40ED-4266-8DAA-C56955C51155 618 | 619 | from 620 | F56381A4-BBE3-4B25-8C03-98A17327E566 - F56381A4-BBE3-4B25-8C03-98A17327E566 621 | to 622 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 - BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 623 | 624 | 625 | variables 626 | 627 | 628 | UUID 629 | AC935E33-1881-44DF-886C-27DA9676279B 630 | identifier 631 | com.apple.Automator.Variable.Storage 632 | name 633 | path 634 | 635 | 636 | UUID 637 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 638 | identifier 639 | com.apple.Automator.Variable.Storage 640 | name 641 | result 642 | 643 | 644 | workflowMetaData 645 | 646 | applicationBundleIDsByPath 647 | 648 | applicationPaths 649 | 650 | inputTypeIdentifier 651 | com.apple.Automator.fileSystemObject 652 | outputTypeIdentifier 653 | com.apple.Automator.nothing 654 | presentationMode 655 | 15 656 | processesInput 657 | 0 658 | serviceInputTypeIdentifier 659 | com.apple.Automator.fileSystemObject 660 | serviceOutputTypeIdentifier 661 | com.apple.Automator.nothing 662 | serviceProcessesInput 663 | 0 664 | systemImageName 665 | NSActionTemplate 666 | useAutomaticInputType 667 | 1 668 | workflowTypeIdentifier 669 | com.apple.Automator.servicesMenu 670 | 671 | 672 | 673 | -------------------------------------------------------------------------------- /src-osx-automator/Convert to skim notes.workflow/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSServices 6 | 7 | 8 | NSBackgroundColorName 9 | background 10 | NSIconName 11 | NSActionTemplate 12 | NSMenuItem 13 | 14 | default 15 | Convert to skim notes 16 | 17 | NSMessage 18 | runWorkflowAsService 19 | NSSendFileTypes 20 | 21 | public.item 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src-osx-automator/Convert to skim notes.workflow/Contents/QuickLook/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/src-osx-automator/Convert to skim notes.workflow/Contents/QuickLook/Preview.png -------------------------------------------------------------------------------- /src-osx-automator/Convert to skim notes.workflow/Contents/QuickLook/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/src-osx-automator/Convert to skim notes.workflow/Contents/QuickLook/Thumbnail.png -------------------------------------------------------------------------------- /src-osx-automator/Convert to skim notes.workflow/Contents/document.wflow: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AMApplicationBuild 6 | 444.39 7 | AMApplicationVersion 8 | 2.9 9 | AMDocumentVersion 10 | 2 11 | actions 12 | 13 | 14 | action 15 | 16 | AMAccepts 17 | 18 | Container 19 | List 20 | Optional 21 | 22 | Types 23 | 24 | com.apple.cocoa.path 25 | 26 | 27 | AMActionVersion 28 | 2.1.1 29 | AMApplication 30 | 31 | Finder 32 | 33 | AMParameterProperties 34 | 35 | AMProvides 36 | 37 | Container 38 | List 39 | Types 40 | 41 | com.apple.cocoa.path 42 | 43 | 44 | AMRequiredResources 45 | 46 | ActionBundlePath 47 | /System/Library/Automator/Get Selected Finder Items 2.action 48 | ActionName 49 | Ausgewählte Finder-Objekte abfragen 50 | ActionParameters 51 | 52 | BundleIdentifier 53 | com.apple.Automator.GetSelectedFinderItems2 54 | CFBundleVersion 55 | 2.1.1 56 | CanShowSelectedItemsWhenRun 57 | 58 | CanShowWhenRun 59 | 60 | Category 61 | 62 | AMCategoryFilesAndFolders 63 | 64 | Class Name 65 | AMGetSelectedFinderItemsAction 66 | InputUUID 67 | 143E0C3E-2CB9-4064-A23D-21752BFB6CDC 68 | Keywords 69 | 70 | OutputUUID 71 | 4C12FD8E-2220-4209-9465-D97281574CFC 72 | UUID 73 | F56381A4-BBE3-4B25-8C03-98A17327E566 74 | UnlocalizedApplications 75 | 76 | Finder 77 | 78 | arguments 79 | 80 | 81 | 82 | 83 | action 84 | 85 | AMAccepts 86 | 87 | Container 88 | List 89 | Optional 90 | 91 | Types 92 | 93 | com.apple.cocoa.string 94 | 95 | 96 | AMActionVersion 97 | 2.0.3 98 | AMApplication 99 | 100 | Automator 101 | 102 | AMParameterProperties 103 | 104 | COMMAND_STRING 105 | 106 | CheckedForUserDefaultShell 107 | 108 | inputMethod 109 | 110 | shell 111 | 112 | source 113 | 114 | 115 | AMProvides 116 | 117 | Container 118 | List 119 | Types 120 | 121 | com.apple.cocoa.string 122 | 123 | 124 | ActionBundlePath 125 | /System/Library/Automator/Run Shell Script.action 126 | ActionName 127 | Shell-Skript ausführen 128 | ActionParameters 129 | 130 | COMMAND_STRING 131 | # -*- coding: utf-8 -*- 132 | """ 133 | skim_pdf. 134 | 135 | Embed Skim notes as PDF notes or convert PDF notes to Skim notes. 136 | Date: 2019-01-30 137 | Version: 1.2 138 | Author: Alexander Gogl 139 | """ 140 | 141 | import sys 142 | import os 143 | # import system, walk, path, argv 144 | 145 | 146 | class SkimPDF(object): 147 | """docstring for SkimPDF.""" 148 | def __init__(self): 149 | self.skimpdf_path = '/Applications/Skim.app/Contents/SharedSupport/skimpdf' 150 | self.embed_suffix = '_embedded' 151 | self.unembed_suffix = '_skim_notes' 152 | self.replace_original = True 153 | pass 154 | 155 | def convert_to_pdf_notes(self, in_pdf): 156 | """Embed skim notes to PDF notes.""" 157 | if self.replace_original is False: 158 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.embed_suffix) 159 | else: 160 | out_pdf = in_pdf 161 | 162 | # Embed notes 163 | cmd = '%s embed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 164 | 165 | os.system(cmd) 166 | pass 167 | 168 | def batch_convert_to_pdf_notes(self, folder): 169 | """Loop through directories in given folder and embed notes.""" 170 | messages = [] 171 | i = 0 172 | for path, subdirs, files in os.walk(folder): 173 | for name in files: 174 | if name.endswith(".pdf"): 175 | i += 1 176 | # embed notes to pdf 177 | pdf_file = "%s/%s" % (path, name) 178 | skim.convert_to_pdf_notes(pdf_file) 179 | 180 | return i 181 | 182 | def convert_to_skim_notes(self, in_pdf): 183 | """Convert PDF notes to Skim notes (unembed).""" 184 | if self.replace_original is False: 185 | out_pdf = "%s%s.pdf" % (in_pdf[:-4], self.skim_suffix) 186 | else: 187 | out_pdf = in_pdf 188 | 189 | # Convert PDF notes to Skim notes 190 | cmd = '%s unembed "%s" "%s"' % (self.skimpdf_path, in_pdf, out_pdf) 191 | 192 | os.system(cmd) 193 | pass 194 | 195 | def batch_convert_to_skim_notes(self, folder): 196 | """Loop through directories in given folder and embed notes.""" 197 | messages = [] 198 | i = 0 199 | for path, subdirs, files in os.walk(folder): 200 | for name in files: 201 | if name.endswith(".pdf"): 202 | i += 1 203 | # embed notes to pdf 204 | pdf_file = "%s/%s" % (path, name) 205 | skim.convert_to_skim_notes(pdf_file) 206 | 207 | return i 208 | 209 | 210 | skim = SkimPDF() 211 | skim.replace_original = True 212 | 213 | paths = sys.argv[1:] 214 | 215 | if len(paths) > 1: 216 | # Multiple elements selected 217 | i = 0 218 | for path in paths: 219 | if os.path.isdir(path): 220 | i += skim.batch_convert_to_skim_notes(path) 221 | else: 222 | skim.convert_to_skim_notes(path) 223 | i += 1 224 | else: 225 | # one element selected 226 | path = paths[0] 227 | if os.path.isdir(path): 228 | i = skim.batch_convert_to_skim_notes(path) 229 | else: 230 | skim.convert_to_skim_notes(path) 231 | i = 1 232 | 233 | message = 'Converted %s files with pdf notes to skim notes' % i 234 | print(message) 235 | 236 | CheckedForUserDefaultShell 237 | 238 | inputMethod 239 | 1 240 | shell 241 | /usr/bin/python 242 | source 243 | 244 | 245 | BundleIdentifier 246 | com.apple.RunShellScript 247 | CFBundleVersion 248 | 2.0.3 249 | CanShowSelectedItemsWhenRun 250 | 251 | CanShowWhenRun 252 | 253 | Category 254 | 255 | AMCategoryUtilities 256 | 257 | Class Name 258 | RunShellScriptAction 259 | InputUUID 260 | ADBA5407-4223-4BC4-A5B9-9F6EDEBC0DE1 261 | Keywords 262 | 263 | Shell 264 | Skript 265 | Befehl 266 | Ausführen 267 | Unix 268 | 269 | OutputUUID 270 | A778BDB9-D6B4-4EDD-AFB6-010FAA6824E7 271 | UUID 272 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 273 | UnlocalizedApplications 274 | 275 | Automator 276 | 277 | arguments 278 | 279 | 0 280 | 281 | default value 282 | 0 283 | name 284 | inputMethod 285 | required 286 | 0 287 | type 288 | 0 289 | uuid 290 | 0 291 | 292 | 1 293 | 294 | default value 295 | 296 | name 297 | source 298 | required 299 | 0 300 | type 301 | 0 302 | uuid 303 | 1 304 | 305 | 2 306 | 307 | default value 308 | 309 | name 310 | CheckedForUserDefaultShell 311 | required 312 | 0 313 | type 314 | 0 315 | uuid 316 | 2 317 | 318 | 3 319 | 320 | default value 321 | 322 | name 323 | COMMAND_STRING 324 | required 325 | 0 326 | type 327 | 0 328 | uuid 329 | 3 330 | 331 | 4 332 | 333 | default value 334 | /bin/sh 335 | name 336 | shell 337 | required 338 | 0 339 | type 340 | 0 341 | uuid 342 | 4 343 | 344 | 345 | isViewVisible 346 | 347 | location 348 | 550.000000:370.000000 349 | nibPath 350 | /System/Library/Automator/Run Shell Script.action/Contents/Resources/Base.lproj/main.nib 351 | 352 | isViewVisible 353 | 354 | 355 | 356 | action 357 | 358 | AMAccepts 359 | 360 | Container 361 | List 362 | Optional 363 | 364 | Types 365 | 366 | * 367 | 368 | 369 | AMActionVersion 370 | v.1.0.2 371 | AMApplication 372 | 373 | Automator 374 | 375 | AMParameterProperties 376 | 377 | variableUUID 378 | 379 | isPathPopUp 380 | 381 | selectedVariableUUID 382 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 383 | 384 | 385 | AMProvides 386 | 387 | Container 388 | List 389 | Types 390 | 391 | * 392 | 393 | 394 | AMRequiredResources 395 | 396 | ActionBundlePath 397 | /System/Library/Automator/Set Value of Variable.action 398 | ActionName 399 | Wert der Variablen festlegen 400 | ActionParameters 401 | 402 | variableUUID 403 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 404 | 405 | BundleIdentifier 406 | com.apple.Automator.SetValueofVariable 407 | CFBundleVersion 408 | 1.0.2 409 | CanShowSelectedItemsWhenRun 410 | 411 | CanShowWhenRun 412 | 413 | Category 414 | 415 | AMCategoryUtilities 416 | 417 | Class Name 418 | Set_Value_of_Variable 419 | InputUUID 420 | B49A8830-5941-4E83-958C-896E92CDBFE4 421 | Keywords 422 | 423 | Variable 424 | Einbinden 425 | Eingabe 426 | Ausgabe 427 | Speicher 428 | 429 | OutputUUID 430 | 8F3A164B-7F71-40DD-B123-BAD5DC9BDA81 431 | UUID 432 | B698066D-B9AA-4959-A92F-B29D59FE0079 433 | UnlocalizedApplications 434 | 435 | Automator 436 | 437 | arguments 438 | 439 | 0 440 | 441 | default value 442 | 443 | name 444 | variableUUID 445 | required 446 | 0 447 | type 448 | 0 449 | uuid 450 | 0 451 | 452 | 453 | isViewVisible 454 | 455 | location 456 | 550.000000:475.000000 457 | nibPath 458 | /System/Library/Automator/Set Value of Variable.action/Contents/Resources/Base.lproj/main.nib 459 | 460 | isViewVisible 461 | 462 | 463 | 464 | action 465 | 466 | AMAccepts 467 | 468 | Container 469 | List 470 | Optional 471 | 472 | Types 473 | 474 | 475 | AMActionVersion 476 | v.1.0 477 | AMApplication 478 | 479 | Automator 480 | 481 | AMParameterProperties 482 | 483 | message 484 | 485 | tokenizedValue 486 | 487 | $(FFB71E96-5A84-4341-A19C-750EC1CC09BD) 488 | 489 | 490 | subtitle 491 | 492 | title 493 | 494 | tokenizedValue 495 | 496 | Convert to skim notes 497 | 498 | 499 | 500 | AMProvides 501 | 502 | Container 503 | List 504 | Types 505 | 506 | 507 | ActionBundlePath 508 | /System/Library/Automator/Display Notification.action 509 | ActionName 510 | Mitteilungen anzeigen 511 | ActionParameters 512 | 513 | message 514 | $(FFB71E96-5A84-4341-A19C-750EC1CC09BD) 515 | subtitle 516 | 517 | title 518 | Convert to skim notes 519 | 520 | BundleIdentifier 521 | com.apple.Automator.Display-Notification 522 | CFBundleVersion 523 | 1.0 524 | CanShowSelectedItemsWhenRun 525 | 526 | CanShowWhenRun 527 | 528 | Category 529 | 530 | AMCategoryUtilities 531 | 532 | Class Name 533 | AMDisplayNotificationAction 534 | IgnoresInput 535 | 536 | InputUUID 537 | EB224DE4-E74B-4168-BF96-740EA509F79A 538 | Keywords 539 | 540 | OutputUUID 541 | 8DA7DAFA-5F16-4F92-9FB4-D57D23A7ECDA 542 | UUID 543 | F9A4A8A2-33F6-452A-BE58-8EF6A996339B 544 | UnlocalizedApplications 545 | 546 | Automator 547 | 548 | arguments 549 | 550 | 0 551 | 552 | default value 553 | 554 | name 555 | subtitle 556 | required 557 | 0 558 | type 559 | 0 560 | uuid 561 | 0 562 | 563 | 1 564 | 565 | default value 566 | 567 | name 568 | title 569 | required 570 | 0 571 | type 572 | 0 573 | uuid 574 | 1 575 | 576 | 2 577 | 578 | default value 579 | 580 | name 581 | message 582 | required 583 | 0 584 | type 585 | 0 586 | uuid 587 | 2 588 | 589 | 590 | isViewVisible 591 | 592 | location 593 | 550.000000:664.000000 594 | nibPath 595 | /System/Library/Automator/Display Notification.action/Contents/Resources/Base.lproj/main.nib 596 | 597 | isViewVisible 598 | 599 | 600 | 601 | connectors 602 | 603 | 4E418ADB-A807-462A-850F-A552329B4C78 604 | 605 | from 606 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 - BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 607 | to 608 | B698066D-B9AA-4959-A92F-B29D59FE0079 - B698066D-B9AA-4959-A92F-B29D59FE0079 609 | 610 | 91E951BA-DDDF-4658-A926-82A68903DA96 611 | 612 | from 613 | F56381A4-BBE3-4B25-8C03-98A17327E566 - F56381A4-BBE3-4B25-8C03-98A17327E566 614 | to 615 | BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 - BC0B6F12-A7B9-404E-BC3E-43D5C6A0A746 616 | 617 | D7A105C1-5B2E-4DC1-9DAE-41A99FB66A3C 618 | 619 | from 620 | B698066D-B9AA-4959-A92F-B29D59FE0079 - B698066D-B9AA-4959-A92F-B29D59FE0079 621 | to 622 | F9A4A8A2-33F6-452A-BE58-8EF6A996339B - F9A4A8A2-33F6-452A-BE58-8EF6A996339B 623 | 624 | 625 | variables 626 | 627 | 628 | UUID 629 | AC935E33-1881-44DF-886C-27DA9676279B 630 | identifier 631 | com.apple.Automator.Variable.Storage 632 | name 633 | path 634 | 635 | 636 | UUID 637 | FFB71E96-5A84-4341-A19C-750EC1CC09BD 638 | identifier 639 | com.apple.Automator.Variable.Storage 640 | name 641 | result 642 | 643 | 644 | workflowMetaData 645 | 646 | applicationBundleIDsByPath 647 | 648 | applicationPaths 649 | 650 | inputTypeIdentifier 651 | com.apple.Automator.fileSystemObject 652 | outputTypeIdentifier 653 | com.apple.Automator.nothing 654 | presentationMode 655 | 15 656 | processesInput 657 | 0 658 | serviceInputTypeIdentifier 659 | com.apple.Automator.fileSystemObject 660 | serviceOutputTypeIdentifier 661 | com.apple.Automator.nothing 662 | serviceProcessesInput 663 | 0 664 | systemImageName 665 | NSActionTemplate 666 | useAutomaticInputType 667 | 1 668 | workflowTypeIdentifier 669 | com.apple.Automator.servicesMenu 670 | 671 | 672 | 673 | -------------------------------------------------------------------------------- /test/test copy/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/test/test copy/test.pdf -------------------------------------------------------------------------------- /test/test copy/test_embedded.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/test/test copy/test_embedded.pdf -------------------------------------------------------------------------------- /test/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/test/test.pdf -------------------------------------------------------------------------------- /test/test_embedded.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandergogl/SkimPDF/beb7fe499b15e7b955856dbf0ba8046d34f6645d/test/test_embedded.pdf --------------------------------------------------------------------------------