├── icon.png ├── Alfred.pyc ├── Notes.pyc ├── Plist.pyc ├── Markdown.pyc ├── icons ├── new.png ├── url.png ├── action.png ├── back.png ├── check.png ├── config.png ├── delete.png ├── donate.png ├── done.png ├── edit.png ├── editor.png ├── help.png ├── icon.png ├── link.png ├── paste.png ├── random.png ├── tasks.png ├── todo.png ├── hashtag.png ├── question.png ├── template.png ├── clipboard.png ├── the-archive.png ├── insert_image.png └── new_from_clipboard.png ├── QuerySplitter.pyc ├── screenshots ├── ar.png ├── arnew.png ├── artag.png ├── arurl.png ├── arhelp.png ├── artask.png ├── arconfig.png ├── ardonate.png ├── arrandom.png ├── ar_action_menu.png ├── arnew_templates.png └── image_file_action.png ├── .github └── FUNDING.yml ├── 0F5540E1-5999-4328-9C24-3C9E18E2746D.png ├── 524CFE69-2161-4618-BC65-7D380B0B3EAD.png ├── 629E7681-4B3B-44F8-931C-617775EE6CFA.png ├── 657FD06E-6635-4C54-88C2-8FF658370FD7.png ├── 8C6B9363-12F2-4E71-8CE7-D1D9777F05C3.png ├── A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4.png ├── A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9.png ├── CB491715-463C-4A1F-BF00-4EF95002AF65.png ├── D7113CA2-175F-4D98-B738-A732E4826D02.png ├── DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D.png ├── ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B.png ├── docs ├── search_content.md ├── search_yaml_tags_only.md ├── template_tag.md ├── use_zettel_id_in_title.md ├── default_date_format.md ├── default_zettel_id_format.md ├── prefer_zettel_id_links.md ├── prefer_filename_to_title.md ├── the_archive_team_id.md ├── exact_match.md └── the_archive_bundle_id.md ├── get_title.py ├── get_zettel_link.py ├── random_note.py ├── get_md_link.py ├── create_note.py ├── fetch_url.py ├── toggle_task.py ├── QuerySplitter.py ├── Plist.py ├── import_image.py ├── search_tags.py ├── search_notes.py ├── search_tasks.py ├── search_actions.py ├── config.py ├── Markdown.py ├── search_templates.py ├── Alfred.py ├── README.md ├── Notes.py └── info.plist /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icon.png -------------------------------------------------------------------------------- /Alfred.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/Alfred.pyc -------------------------------------------------------------------------------- /Notes.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/Notes.pyc -------------------------------------------------------------------------------- /Plist.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/Plist.pyc -------------------------------------------------------------------------------- /Markdown.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/Markdown.pyc -------------------------------------------------------------------------------- /icons/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/new.png -------------------------------------------------------------------------------- /icons/url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/url.png -------------------------------------------------------------------------------- /icons/action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/action.png -------------------------------------------------------------------------------- /icons/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/back.png -------------------------------------------------------------------------------- /icons/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/check.png -------------------------------------------------------------------------------- /icons/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/config.png -------------------------------------------------------------------------------- /icons/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/delete.png -------------------------------------------------------------------------------- /icons/donate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/donate.png -------------------------------------------------------------------------------- /icons/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/done.png -------------------------------------------------------------------------------- /icons/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/edit.png -------------------------------------------------------------------------------- /icons/editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/editor.png -------------------------------------------------------------------------------- /icons/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/help.png -------------------------------------------------------------------------------- /icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/icon.png -------------------------------------------------------------------------------- /icons/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/link.png -------------------------------------------------------------------------------- /icons/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/paste.png -------------------------------------------------------------------------------- /icons/random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/random.png -------------------------------------------------------------------------------- /icons/tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/tasks.png -------------------------------------------------------------------------------- /icons/todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/todo.png -------------------------------------------------------------------------------- /QuerySplitter.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/QuerySplitter.pyc -------------------------------------------------------------------------------- /icons/hashtag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/hashtag.png -------------------------------------------------------------------------------- /icons/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/question.png -------------------------------------------------------------------------------- /icons/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/template.png -------------------------------------------------------------------------------- /screenshots/ar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/ar.png -------------------------------------------------------------------------------- /icons/clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/clipboard.png -------------------------------------------------------------------------------- /icons/the-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/the-archive.png -------------------------------------------------------------------------------- /screenshots/arnew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arnew.png -------------------------------------------------------------------------------- /screenshots/artag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/artag.png -------------------------------------------------------------------------------- /screenshots/arurl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arurl.png -------------------------------------------------------------------------------- /icons/insert_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/insert_image.png -------------------------------------------------------------------------------- /screenshots/arhelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arhelp.png -------------------------------------------------------------------------------- /screenshots/artask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/artask.png -------------------------------------------------------------------------------- /screenshots/arconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arconfig.png -------------------------------------------------------------------------------- /screenshots/ardonate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/ardonate.png -------------------------------------------------------------------------------- /screenshots/arrandom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arrandom.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: pryley 4 | liberapay: pryley 5 | -------------------------------------------------------------------------------- /icons/new_from_clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/icons/new_from_clipboard.png -------------------------------------------------------------------------------- /screenshots/ar_action_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/ar_action_menu.png -------------------------------------------------------------------------------- /screenshots/arnew_templates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/arnew_templates.png -------------------------------------------------------------------------------- /screenshots/image_file_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/screenshots/image_file_action.png -------------------------------------------------------------------------------- /0F5540E1-5999-4328-9C24-3C9E18E2746D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/0F5540E1-5999-4328-9C24-3C9E18E2746D.png -------------------------------------------------------------------------------- /524CFE69-2161-4618-BC65-7D380B0B3EAD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/524CFE69-2161-4618-BC65-7D380B0B3EAD.png -------------------------------------------------------------------------------- /629E7681-4B3B-44F8-931C-617775EE6CFA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/629E7681-4B3B-44F8-931C-617775EE6CFA.png -------------------------------------------------------------------------------- /657FD06E-6635-4C54-88C2-8FF658370FD7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/657FD06E-6635-4C54-88C2-8FF658370FD7.png -------------------------------------------------------------------------------- /8C6B9363-12F2-4E71-8CE7-D1D9777F05C3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/8C6B9363-12F2-4E71-8CE7-D1D9777F05C3.png -------------------------------------------------------------------------------- /A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4.png -------------------------------------------------------------------------------- /A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9.png -------------------------------------------------------------------------------- /CB491715-463C-4A1F-BF00-4EF95002AF65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/CB491715-463C-4A1F-BF00-4EF95002AF65.png -------------------------------------------------------------------------------- /D7113CA2-175F-4D98-B738-A732E4826D02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/D7113CA2-175F-4D98-B738-A732E4826D02.png -------------------------------------------------------------------------------- /DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D.png -------------------------------------------------------------------------------- /ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pryley/alfred-the-archive/HEAD/ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B.png -------------------------------------------------------------------------------- /docs/search_content.md: -------------------------------------------------------------------------------- 1 | ### Search Content (`search_content`) 2 | 3 | > Default value: `False` 4 | 5 | When set to `True`, both the filenames and note contents will be searched. 6 | 7 | When set to `False`, only the filenames will be searched. 8 | -------------------------------------------------------------------------------- /get_title.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from Notes import Search 6 | import sys 7 | 8 | query = Tools.getArgv(1) 9 | title = Search().getNoteTitle(query) 10 | 11 | sys.stdout.write(title) 12 | -------------------------------------------------------------------------------- /docs/search_yaml_tags_only.md: -------------------------------------------------------------------------------- 1 | ### Search YAML Tags Only (`search_yaml_tags_only`) 2 | 3 | > Default value: `False` 4 | 5 | When set to `True`, tags will only be searched for in the YAML front matter. 6 | 7 | When set to `False`, tags will be searched for in the entire note. 8 | -------------------------------------------------------------------------------- /docs/template_tag.md: -------------------------------------------------------------------------------- 1 | ### Template Tag (`template_tag`) 2 | 3 | > Default value: `#template` 4 | 5 | The template tag defines which notes are used as templates. Add the template tag somewhere in the first 10 lines of a note and it will be recognized as an available template when you create a note. 6 | -------------------------------------------------------------------------------- /get_zettel_link.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from Notes import Search 6 | import sys 7 | 8 | query = Tools.getArgv(1) 9 | title = Search().getNoteLinkTitle(query).strip() 10 | output = '[[' + title + ']]' 11 | 12 | sys.stdout.write(output) 13 | -------------------------------------------------------------------------------- /docs/use_zettel_id_in_title.md: -------------------------------------------------------------------------------- 1 | ### Use Zettel ID in Title (`use_zettel_id_in_title`) 2 | 3 | > Default value: `False` 4 | 5 | When set to `True`, the Zettel ID will be included in the `{title}` placeholder of your templates. 6 | 7 | When set to `False`, the Zettel ID will not be included in the `{title}` placeholder of your templates. 8 | -------------------------------------------------------------------------------- /docs/default_date_format.md: -------------------------------------------------------------------------------- 1 | ### Default Date Format (`default_date_format`) 2 | 3 | > Default value: `%A, %d %B, %Y at %H:%M` 4 | 5 | This option defines the datetime format used for the `{date}` placeholder in your templates. 6 | 7 | Please refer to the [Python strftime reference](https://strftime.org/) for the available datetime variables. 8 | -------------------------------------------------------------------------------- /random_note.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | import random 5 | import sys 6 | from Notes import Search 7 | 8 | search = Search() 9 | sorted_file_list = search.getFilesListSorted() 10 | file = random.choice(sorted_file_list) 11 | output = search.getNoteFilename(file['path']) 12 | 13 | sys.stdout.write(output) 14 | -------------------------------------------------------------------------------- /docs/default_zettel_id_format.md: -------------------------------------------------------------------------------- 1 | ### Default Zettel ID Format (`default_zettel_id_format`) 2 | 3 | > Default value: `%Y%m%d%H%M` 4 | 5 | This option defines the datetime format used for the generated Zettel ID and the `{zettel_id}` placeholder in your templates. 6 | 7 | Please refer to the [Python strftime reference](https://strftime.org/) for the available datetime variables. 8 | -------------------------------------------------------------------------------- /docs/prefer_zettel_id_links.md: -------------------------------------------------------------------------------- 1 | ### Prefer Zettel ID Links (`prefer_zettel_id_links`) 2 | 3 | > Default value: `False` 4 | 5 | When set to `True`, the Zettel ID (if one exists) will be used as the link title in markdown and wiki links (i.e. `[[202006131200]]`). 6 | 7 | When set to `False`, the full note title will be used in markdown and wiki links (i.e. `[[202006131200 The Note Title]]`). 8 | -------------------------------------------------------------------------------- /get_md_link.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from Notes import Search 6 | from urllib.request import pathname2url 7 | import os 8 | import sys 9 | 10 | query = Tools.getArgv(1) 11 | title = Search().getNoteTitle(query).strip() 12 | filename = pathname2url(os.path.basename(query)) 13 | output = '[' + title + '](' + filename + ')' 14 | 15 | sys.stdout.write(output) 16 | -------------------------------------------------------------------------------- /docs/prefer_filename_to_title.md: -------------------------------------------------------------------------------- 1 | ### Prefer Filename to Title (`prefer_filename_to_title`) 2 | 3 | > Default value: `True` 4 | 5 | This option defines which value is used when matching a search result in The Archive (i.e. `thearchive://match/{value}`). 6 | 7 | When set to `True`, the note filename will be used. 8 | 9 | When set to `False`, the note title (if entered as `# Note Title`) will be used if it exists instead of the filename. 10 | -------------------------------------------------------------------------------- /docs/the_archive_team_id.md: -------------------------------------------------------------------------------- 1 | ### The Archive Team ID (`the_archive_team_id`) 2 | 3 | > Default value: `FRMDA3XRGC` 4 | 5 | A team ID (or team identifier) is generated by Apple and uniquely identifies the developer of an application in Apple's ecosystem. 6 | 7 | This workflow uses the team identifier together with [the_archive_bundle_id](#the-archive-bundle-id-the_archive_bundle_id) to get the saved preferences of The Archive. 8 | 9 | This value should never need changing. 10 | -------------------------------------------------------------------------------- /docs/exact_match.md: -------------------------------------------------------------------------------- 1 | ### Exact Match (`exact_match`) 2 | 3 | > Default value: `False` 4 | 5 | This option defines if the search should match the exact search term (`True`) or the string (`False`). When the value is set to `True` it is possible to enhance the search term with wildcards. 6 | 7 | When set to `True`, searching for `Books` will match `Books` but not `Bookstore`. However, `Books*` will match both `Books` and `Bookstore`. 8 | 9 | When set to `False`, searching for `Books` will match `Books` as well as `Bookstore`. 10 | -------------------------------------------------------------------------------- /docs/the_archive_bundle_id.md: -------------------------------------------------------------------------------- 1 | ### The Archive Bundle ID (`the_archive_bundle_id`) 2 | 3 | > Default value: `de.zettelkasten.TheArchive` 4 | 5 | A bundle ID (or bundle identifier) uniquely identifies an application in Apple's ecosystem. This means that no two applications can have the same bundle identifier. 6 | 7 | This workflow uses the bundle identifier together with [the_archive_team_id](#the-archive-team-id-the_archive_team_id) to get the saved preferences of The Archive. 8 | 9 | This value should never need changing. 10 | -------------------------------------------------------------------------------- /create_note.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from Notes import Note, Search 6 | from QuerySplitter import QuerySplitter 7 | import sys 8 | 9 | query = Tools.getArgv(1) 10 | clipboard = Tools.getEnv('clipboard') 11 | template = Tools.getEnv('template') 12 | paste = Tools.getEnv('paste') 13 | 14 | qs = QuerySplitter(query) 15 | 16 | if query: 17 | note = Note( 18 | content=str() if not paste else clipboard, 19 | tags=qs.tags, 20 | template_path=template, 21 | title=qs.title, 22 | zettel_id=qs.zettel_id, 23 | ) 24 | file_path = note.createNote() 25 | output = Search().getNoteFilename(file_path) 26 | 27 | sys.stdout.write(output) 28 | -------------------------------------------------------------------------------- /fetch_url.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from Markdown import Markdown 6 | from Notes import Search 7 | import os 8 | import sys 9 | 10 | search = Search() 11 | ext = search.getDefaultExtension() 12 | path = Tools.getNotesPath() 13 | query = Tools.getArgv(1) 14 | 15 | markdown = Markdown(query) 16 | today_time = Tools.getTodayDate(fmt="%Y-%m-%d %H-%M") 17 | content = markdown.getMarkdownContent() 18 | file_name = markdown.parseFilename(markdown.getTitle()) 19 | if file_name == str(): 20 | file_name = Tools.strJoin('WebClip from ', today_time) 21 | filepath = os.path.join(path, "{0}{1}".format(file_name, ext)) 22 | markdown.writeMarkdown(content, filepath) 23 | 24 | sys.stdout.write(file_name) 25 | -------------------------------------------------------------------------------- /toggle_task.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | import re 6 | import sys 7 | 8 | def replace(file, pattern, subst): 9 | file_handle = open(file, 'r') 10 | file_string = file_handle.read() 11 | file_handle.close() 12 | file_string = (re.sub(pattern, subst, file_string)) 13 | file_handle = open(file, 'w') 14 | file_handle.write(file_string) 15 | file_handle.close() 16 | 17 | path = Tools.getArgv(1) 18 | todo = Tools.getEnv('todo') 19 | status = Tools.getEnv('todo_status') 20 | query = Tools.getEnv('todo_query') 21 | 22 | old_val = ' ' if status == 'pending' else 'x' 23 | new_val = ' ' if old_val == 'x' else 'x' 24 | 25 | replace(path, "([-|\*] \[){0}(\] {1})".format(old_val, todo), "\\1{0}\\2".format(new_val)) 26 | 27 | sys.stdout.write(query) 28 | -------------------------------------------------------------------------------- /QuerySplitter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | class QuerySplitter(object): 5 | 6 | def __init__(self, query): 7 | self.tags = str() 8 | self.title = str() 9 | self.zettel_id = str() 10 | self._split(query) 11 | 12 | def _isZettelId(self, text): 13 | zettel_id = str(text) 14 | return True if len(zettel_id) == 12 and zettel_id.isdigit() else False 15 | 16 | def _split(self, query): 17 | parts = query.split(' ') 18 | title_list = list() 19 | tag_list = list() 20 | for part in parts: 21 | if str(part).startswith('#'): 22 | tag_list.append(part) 23 | elif self._isZettelId(part) and self.zettel_id == str(): 24 | self.zettel_id = part 25 | else: 26 | title_list.append(part) 27 | self.title = ' '.join(title_list) 28 | self.tags = ' '.join(tag_list) 29 | -------------------------------------------------------------------------------- /Plist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | import plistlib 5 | 6 | class Plist: 7 | 8 | def __init__(self): 9 | self.info = self.readPlist('info.plist') 10 | 11 | def deleteVariable(self, variable): 12 | try: 13 | del self.info['variables'][variable] 14 | self.writePlist(self.info, 'info.plist') 15 | except KeyError: 16 | pass 17 | 18 | def getConfig(self): 19 | return self.info['variables'] 20 | 21 | def getVariable(self, variable): 22 | try: 23 | return self.info['variables'][variable] 24 | except KeyError: 25 | pass 26 | 27 | @staticmethod 28 | def readPlist(filepath): 29 | with open(filepath, 'rb') as fp: 30 | plistData = plistlib.load(fp) 31 | return plistData 32 | 33 | def setVariable(self, variable, value): 34 | self.info['variables'][variable] = value 35 | self.writePlist(self.info, 'info.plist') 36 | 37 | @staticmethod 38 | def writePlist(dataObject, filepath): 39 | with open(filepath, 'wb') as fp: 40 | plistlib.dump(dataObject, fp) 41 | -------------------------------------------------------------------------------- /import_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from shutil import copy2 6 | import os 7 | import re 8 | import sys 9 | import urllib.request, urllib.parse, urllib.error 10 | 11 | def copyFile(source, target_dir): 12 | file_name = str() 13 | if os.path.isfile(source): 14 | file_name = os.path.basename(source) 15 | valid_file_name = re.sub('[^\w_.)(-]', '_', file_name) 16 | destination = os.path.join(target_dir, valid_file_name) 17 | copy2(source, destination) 18 | file_name = valid_file_name 19 | else: 20 | raise ValueError 21 | return os.path.join(target_dir, file_name) 22 | 23 | def getMediaFolder(): 24 | notes_path = Tools.getNotesPath() 25 | media_dir = Tools.settings('resourcesSubfolder', 'media') 26 | media_path = os.path.join(notes_path, media_dir) 27 | if not(os.path.exists(media_path)): 28 | os.mkdir(media_path) 29 | return media_path 30 | 31 | source_file = Tools.getArgv(1) 32 | target_dir = getMediaFolder() 33 | image_file = copyFile(source_file, target_dir) 34 | file_url = urllib.request.pathname2url(image_file) 35 | link = '![{0}]({1})'.format(os.path.basename(image_file), file_url) 36 | 37 | sys.stdout.write(link) 38 | -------------------------------------------------------------------------------- /search_tags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from Notes import Search 6 | 7 | items = Items() 8 | query = Tools.getArgv(1) 9 | search = Search() 10 | 11 | if query is str(): 12 | tag_results = search.tags(query, 'tag', reverse=False) 13 | else: 14 | tag_results = search.tags(query, 'count', reverse=True) 15 | 16 | if bool(tag_results): 17 | for tag, counter in list(tag_results.items()): 18 | items.setItem( 19 | arg=tag, # we cannot yet send a hash character with `thearchive://match/{query}` 20 | subtitle="{0} Hit(s), (\u2318 Paste Into Frontmost Application)".format(counter), 21 | title=tag, 22 | valid=True, 23 | ) 24 | items.setIcon('icons/hashtag.png', 'image') 25 | items.addMod( 26 | arg="#{0} ".format(tag), 27 | icon_path='icons/paste.png', 28 | icon_type='image', 29 | key='cmd', 30 | subtitle='Paste this tag into the frontmost application', 31 | ) 32 | items.addItem() 33 | else: 34 | items.setItem( 35 | subtitle="No Tags matches search term", 36 | title="No Tags found!", 37 | valid=False, 38 | ) 39 | items.addItem() 40 | 41 | items.write() 42 | -------------------------------------------------------------------------------- /search_notes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from Notes import Search 6 | 7 | items = Items() 8 | query = Tools.getArgv(1) 9 | search = Search() 10 | search_terms, search_type = search.getSearchConfig(query) 11 | 12 | if len(search_terms) > 0: 13 | sorted_file_list = search.notes(search_terms, search_type) 14 | else: 15 | sorted_file_list = search.getFilesListSorted() 16 | 17 | for file in sorted_file_list: 18 | c_date = Tools.getDateStr(file['ctime']) 19 | m_date = Tools.getDateStr(file['mtime']) 20 | items.setItem( 21 | arg=file['path'], 22 | subtitle="Created: {0}, Modified: {1} (\u2318 Actions, \u2325 Paste Wiki Link, \u21E7 Quicklook)".format(c_date, m_date), 23 | title=file['title'], 24 | type="file", 25 | ) 26 | items.addMod( 27 | arg="{0}|>{1}".format(file['path'], query), 28 | icon_path="icons/action.png", 29 | icon_type="image", 30 | key="cmd", 31 | subtitle="Enter Actions Menu for the Note...", 32 | ) 33 | items.addMod( 34 | arg=file['title'], 35 | icon_path="icons/paste.png", 36 | icon_type="image", 37 | key="alt", 38 | subtitle="Paste wiki link into frontmost app", 39 | ) 40 | items.addItem() 41 | 42 | if len(items.getItems(response_type="dict")['items']) == 0: 43 | items.setItem( 44 | arg=query, 45 | subtitle="Create note with title \"{0}\"?".format(query), 46 | title="Nothing found...", 47 | ) 48 | items.setIcon('icons/new.png', 'image') 49 | items.addItem() 50 | 51 | items.write() 52 | -------------------------------------------------------------------------------- /search_tasks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from Notes import Search 6 | 7 | items = Items() 8 | query = Tools.getArgv(1) 9 | search = Search() 10 | 11 | tasks = search.tasks(query) 12 | 13 | if len(tasks) > 0: 14 | for file in tasks: 15 | file_title = file['title'] if file['title'] != str() else search.getNoteFilename(file['path']) 16 | items.setItem( 17 | arg=file['path'], 18 | subtitle="\u2192 {0} (\u2318 Open in The Archive, \u2325 Open in Default Editor)".format(file['filename']), 19 | title=file['todo'], 20 | type='file', 21 | valid=True, 22 | variables={ 23 | "todo": file['todo'], 24 | "todo_query": query, 25 | "todo_status": file['status'], 26 | }, 27 | ) 28 | items.addMod( 29 | arg=file['path'], 30 | icon_path="icons/the-archive.png", 31 | icon_type="image", 32 | key="cmd", 33 | subtitle="Open \"{0}\" in The Archive".format(file['filename']), 34 | ) 35 | items.addMod( 36 | arg=file['path'], 37 | icon_path="icons/editor.png", 38 | icon_type="image", 39 | key="alt", 40 | subtitle="Open \"{0}\" in the default editor".format(file['filename']), 41 | ) 42 | items.setIcon('icons/todo.png' if file['status'] == 'pending' else 'icons/done.png', 'image') 43 | items.addItem() 44 | else: 45 | items.setItem( 46 | title="No tasks found!", 47 | subtitle="No task matches the search term", 48 | valid=False, 49 | ) 50 | items.addItem() 51 | items.write() 52 | -------------------------------------------------------------------------------- /search_actions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from Notes import Search 6 | from urllib.request import pathname2url 7 | import os 8 | 9 | items = Items() 10 | query = Tools.getEnv("path_query2") 11 | search = Search() 12 | note_path = Tools.getEnv("path_query1") 13 | note_title = search.getNoteTitle(note_path) 14 | note_link_title = search.getNoteLinkTitle(note_path) 15 | filename = pathname2url(os.path.basename(note_path)) 16 | back_query = "" if not query else query 17 | 18 | actions = [ 19 | { 20 | "arg": "back|>{0}".format(query), 21 | "icon": "icons/back.png", 22 | "subtitle": "Back to Search with query: {0}".format(back_query), 23 | "title": "Back", 24 | }, 25 | { 26 | "arg": "markdown_link|>[{0}]({1})".format(note_link_title, filename), 27 | "icon": "icons/link.png", 28 | "subtitle": "Copy a Markdown Link for \"{0}\" to the Clipboard".format(note_title), 29 | "title": "Markdown Link", 30 | }, 31 | { 32 | "arg": "wiki_link|>[[{0}]]".format(note_link_title), 33 | "icon": "icons/link.png", 34 | "subtitle": "Copy a Wiki Link for \"{0}\" to the Clipboard".format(note_title), 35 | "title": "Wiki Link", 36 | }, 37 | { 38 | "arg": "editor|>{0}".format(note_path), 39 | "icon": "icons/editor.png", 40 | "subtitle": "Open \"{0}\" with the default editor".format(os.path.basename(note_path)), 41 | "title": "External Editor", 42 | }, 43 | { 44 | "arg": "delete|>{0}".format(note_path), 45 | "icon": "icons/delete.png", 46 | "subtitle": "Delete \"{0}\"".format(os.path.basename(note_path)), 47 | "title": "Delete Note", 48 | }, 49 | ] 50 | 51 | for a in actions: 52 | items.setItem( 53 | arg=a.get("arg"), 54 | subtitle=a.get("subtitle"), 55 | title=a.get("title"), 56 | ) 57 | items.setIcon(a.get("icon"), "image") 58 | items.addItem() 59 | 60 | items.write() 61 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from collections import OrderedDict 6 | from Plist import Plist 7 | import os 8 | 9 | def get_selection(key, query): 10 | variables = get_variables() 11 | if key in variables: 12 | v = variables[key] 13 | isValid = False if query == str() else True 14 | items.setItem( 15 | arg = "set|>{0}|>{1}".format(key, query), 16 | quicklookurl = "{0}/docs/{1}.md".format(workflow_dir, key), 17 | subtitle = "Add new value and press enter (\u2318 Delete value, \u21E7 for Help)", 18 | title = "Change {0}: {1}".format(key, v), 19 | valid = isValid, 20 | ) 21 | items.addMod( 22 | arg = 'set|>{0}|>'.format(key), 23 | key = 'cmd', 24 | subtitle = 'Delete Value', 25 | ) 26 | items.setIcon('icons/edit.png', 'image') 27 | items.addItem() 28 | else: 29 | items.setItem( 30 | title = "Variable not found", 31 | valid = False 32 | ) 33 | items.addItem() 34 | 35 | def get_variables(): 36 | config = Plist().getConfig() 37 | return OrderedDict(sorted(config.items())) 38 | 39 | def print_config(query): 40 | variables = get_variables() 41 | for variable, value in list(variables.items()): 42 | if query == str() or query in variable: 43 | v_subtitle = '' if value == str() else value 44 | items.setItem( 45 | arg = "selection|>{0}|>{1}".format(variable, value), 46 | quicklookurl = "{0}/docs/{1}.md".format(workflow_dir, variable), 47 | subtitle = "Value: {0} (\u21E7 for Help)".format(v_subtitle), 48 | title = variable, 49 | ) 50 | icon = 'icons/check.png' if value != str() else 'icons/question.png' 51 | items.setIcon(icon, 'image') 52 | items.addItem() 53 | 54 | def write_config(key, val): 55 | value = Tools.normalize(val) 56 | Plist().setVariable(key, value) 57 | 58 | query = Tools.getArgv(1) 59 | action_key_value = Tools.getEnv('action_key_value') 60 | [action, key, value] = action_key_value.split('|>') if action_key_value != str() else [str(), str(), str()] 61 | workflow_dir = os.getcwd() 62 | query = Tools.getArgv(1) 63 | 64 | items = Items() 65 | 66 | if action == str(): 67 | print_config(query) 68 | elif action == 'selection': 69 | get_selection(key, query) 70 | else: 71 | write_config(key, value) 72 | print_config(query) 73 | 74 | items.write() 75 | -------------------------------------------------------------------------------- /Markdown.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | import html 6 | import os 7 | import re 8 | import urllib.request 9 | import urllib.error 10 | import urllib.parse 11 | 12 | 13 | class Markdown(object): 14 | 15 | PANDOC = 'pandoc -f html-native_divs-native_spans -t gfm --strip-comments --markdown-headings=atx ' 16 | 17 | def __init__(self, url): 18 | self.url = url 19 | self.html = self._fetchHtml().decode('utf-8') 20 | self.md = self._fetchMd() 21 | 22 | def _fetchHtml(self): 23 | try: 24 | r = urllib.request.urlopen(self.url) 25 | response = r.read() 26 | except: 27 | response = "" + self.url + "" 28 | pass 29 | return response 30 | 31 | def _fetchMd(self): 32 | try: 33 | cmd = '{0} {1}'.format(self.PANDOC, self.url) 34 | md = os.popen(cmd) 35 | resp = md.read() 36 | except: 37 | resp = "[{0}]({0})".format(self.url) 38 | pass 39 | return resp 40 | 41 | @staticmethod 42 | def _htmlDecode(string): 43 | string = urllib.parse.unquote(string) 44 | # return string 45 | return html.unescape(string) 46 | 47 | def _markdownHeader(self): 48 | return "---\n" \ 49 | "Title: {title}\n" \ 50 | "Created: {date}\n" \ 51 | "Tags: #WebClip\n" \ 52 | "Url: {url}\n" \ 53 | "---\n".format(date=Tools.getTodayDate(), url=self.getMdUrl(), title=self.getTitle()) 54 | 55 | def getHtml(self): 56 | return self.html 57 | 58 | def getMarkdownContent(self): 59 | out = self._markdownHeader() 60 | out += self.getMd() 61 | return out 62 | 63 | def getMd(self): 64 | return self.md 65 | 66 | def getMdUrl(self): 67 | page_url = "[{0}]({1})".format(self.getTitle(), self.getUrl()) 68 | return page_url 69 | 70 | def getTitle(self): 71 | res = re.findall(r'[\n\t\s]*(.+)[\n\t\s]*', self.html, re.MULTILINE) 72 | return self._htmlDecode(''.join(res)) 73 | 74 | def getUrl(self): 75 | return self.url 76 | 77 | def parseFilename(self, filename): 78 | to_replace = ['/', '\\', ':'] 79 | tmp = filename.strip() 80 | for i in to_replace: 81 | tmp = tmp.replace(i, '-') 82 | return tmp 83 | 84 | def writeMarkdown(self, content, path): 85 | with open(path, "w+") as file: 86 | file.write(content) 87 | -------------------------------------------------------------------------------- /search_templates.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Items, Tools 5 | from Notes import Notes, Search 6 | 7 | items = Items() 8 | notes = Notes() 9 | search = Search() 10 | zettel_id = Tools.getZettelId() 11 | query = Tools.getArgv(1) 12 | query_alt = "{0} {1}".format(zettel_id, query) 13 | zettel_action = "\u2318 Add Zettel ID" 14 | paste_action = "\u2325 Paste clipboard" 15 | quicklook_action = "\u21E7 Quicklook" 16 | 17 | if notes.useZettelId(): 18 | query_alt = query 19 | query = "{0} {1}".format(zettel_id, query_alt) 20 | zettel_action = "\u2318 Remove Zettel ID" 21 | 22 | items.setItem( 23 | arg="{0}|>|>".format(query), 24 | subtitle="\"{0}\" ({1}, {2})".format(query, zettel_action, paste_action), 25 | title="Create note", 26 | ) 27 | items.addMod( 28 | arg="{0}|>|>".format(query_alt), 29 | key="cmd", 30 | subtitle="\"{0}\" ({1})".format(query_alt, paste_action), 31 | ) 32 | items.addMod( 33 | arg="{0}|>|>paste".format(query), 34 | icon_path="icons/new_from_clipboard.png", 35 | icon_type="image", 36 | key="alt", 37 | subtitle="\"{0}\" ({1})".format(query, zettel_action), 38 | ) 39 | items.addMod( 40 | arg="{0}|>|>paste".format(query_alt), 41 | icon_path="icons/new_from_clipboard.png", 42 | icon_type="image", 43 | key="cmd+alt", 44 | subtitle="\"{0}\"".format(query_alt), 45 | ) 46 | items.setIcon('icons/new.png', 'image') 47 | items.addItem() 48 | 49 | templates_list = search.templates() 50 | 51 | if len(templates_list) > 0: 52 | for file in templates_list: 53 | items.setItem( 54 | arg="{0}|>{1}|>".format(query, file['path']), 55 | subtitle="\"{0}\" ({1}, {2}. {3})".format(query, zettel_action, paste_action, quicklook_action), 56 | title="Create note from template: {0}".format(file['filename']), 57 | type='file', 58 | quicklookurl=file['path'], 59 | ) 60 | items.addMod( 61 | arg="{0}|>{1}|>".format(query_alt, file['path']), 62 | key="cmd", 63 | subtitle="\"{0}\" ({1})".format(query_alt, paste_action), 64 | ) 65 | items.addMod( 66 | arg="{0}|>{1}|>paste".format(query, file['path']), 67 | icon_path="icons/paste.png", 68 | icon_type="image", 69 | key="alt", 70 | subtitle="\"{0}\" ({1})".format(query, zettel_action), 71 | ) 72 | items.addMod( 73 | arg="{0}|>{1}|>paste".format(query_alt, file['path']), 74 | icon_path="icons/paste.png", 75 | icon_type="image", 76 | key="cmd+alt", 77 | subtitle="\"{0}\"".format(query_alt), 78 | ) 79 | items.setIcon('icons/template.png', 'image') 80 | items.addItem() 81 | 82 | items.write() 83 | -------------------------------------------------------------------------------- /Alfred.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from datetime import datetime, timedelta 5 | from Plist import Plist 6 | import json 7 | import os 8 | import re 9 | import sys 10 | import time 11 | import urllib.request, urllib.error, urllib.parse 12 | 13 | class Items(object): 14 | 15 | def __init__(self): 16 | self.item = {} 17 | self.items = [] 18 | self.mods = {} 19 | 20 | def _defineIcon(self, path, m_type=""): 21 | icon = {} 22 | if m_type != "": 23 | icon.update({"type": m_type}) 24 | icon.update({"path": path}) 25 | return icon 26 | 27 | def addItem(self): 28 | self.addModsToItem() 29 | self.items.append(self.item) 30 | self.item = {} 31 | self.mods = {} 32 | 33 | def addMod(self, key, arg, subtitle, valid=True, icon_path="", icon_type=""): 34 | valid_keys = {"alt", "cmd", "shift", "ctrl", "fn", "cmd+alt"} 35 | if key not in valid_keys: 36 | raise ValueError("Key must be in: %s" % valid_keys) 37 | mod = {} 38 | mod.update({"arg": arg}) 39 | mod.update({"subtitle": subtitle}) 40 | mod.update({"valid": valid}) 41 | if icon_path != "": 42 | the_icon = self._defineIcon(icon_path, icon_type) 43 | mod.update({"icon": the_icon}) 44 | self.mods.update({key: mod}) 45 | 46 | def addModsToItem(self): 47 | if bool(self.mods): 48 | self.setKeyValue("mods", self.mods) 49 | self.mods = dict() 50 | 51 | def getItem(self, d_type=""): 52 | if d_type == "": 53 | return self.item 54 | else: 55 | return json.dumps(self.item, indent=4) 56 | 57 | def getItems(self, response_type="json"): 58 | valid_keys = {"json", "dict"} 59 | if response_type not in valid_keys: 60 | raise ValueError("Type must be in: %s" % valid_keys) 61 | the_items = dict() 62 | the_items.update({"items": self.items}) 63 | if response_type == "dict": 64 | return the_items 65 | elif response_type == "json": 66 | return json.dumps(the_items, indent=4) 67 | 68 | def setIcon(self, m_path, m_type=""): 69 | self.setKeyValue("icon", self._defineIcon(m_path, m_type)) 70 | 71 | def setItem(self, **kwargs): 72 | for key, value in list(kwargs.items()): 73 | self.setKeyValue(key, value) 74 | 75 | def setKeyValue(self, key, value): 76 | self.item.update({key: value}) 77 | 78 | def updateItem(self, id, key, value): 79 | dict_item = self.items[id] 80 | kv = dict_item[key] 81 | dict_item[key] = kv + value 82 | self.items[id] = dict_item 83 | 84 | def write(self, response_type='json'): 85 | output = self.getItems(response_type=response_type) 86 | sys.stdout.write(output) 87 | 88 | class Tools(object): 89 | 90 | @staticmethod 91 | def chop(string, suffix): 92 | if string.endswith(suffix): 93 | return string[:-len(suffix)] 94 | return string 95 | 96 | @staticmethod 97 | def getArgv(i): 98 | try: 99 | return sys.argv[i] 100 | except IndexError: 101 | return str() 102 | pass 103 | 104 | @staticmethod 105 | def getDataDir(): 106 | data_dir = os.getenv('alfred_workflow_data') 107 | if not(os.path.isdir(data_dir)): 108 | os.mkdir(data_dir) 109 | return data_dir 110 | 111 | @staticmethod 112 | def getDateStr(float_time, fmt='%Y-%m-%d'): 113 | return time.strftime(fmt, time.gmtime(float_time)) 114 | 115 | @staticmethod 116 | def getEnv(var): 117 | return os.getenv(var) if os.getenv(var) is not None else str() 118 | 119 | @staticmethod 120 | def getNotesPath(): 121 | archive_url = Tools.settings('archiveURL') 122 | path = urllib.parse.unquote(archive_url[len("file://"):]) 123 | return path 124 | 125 | @staticmethod 126 | def getTodayDate(fmt="%d.%m.%Y"): 127 | default_date_format = os.getenv('default_date_format') 128 | date_format = fmt if default_date_format == str() else default_date_format 129 | now = datetime.now() 130 | return now.strftime(date_format) 131 | 132 | @staticmethod 133 | def getZettelId(): 134 | default_zettel_id_format = os.getenv('default_zettel_id_format'); 135 | zettel_id_format = "%Y%m%d%H%M" if default_zettel_id_format == str() else default_zettel_id_format 136 | now = datetime.now() 137 | zettel_id = now.strftime(zettel_id_format) 138 | if zettel_id.isdigit(): 139 | path = Tools.getNotesPath() 140 | while Tools.zettelIdExists(path, zettel_id): 141 | zettel_id_date = datetime.strptime(zettel_id, zettel_id_format) 142 | new_zettel_id_date = zettel_id_date + timedelta(minutes=1) 143 | zettel_id = new_zettel_id_date.strftime(zettel_id_format) 144 | return zettel_id; 145 | 146 | @staticmethod 147 | def increment(file_name): 148 | increment = 1 149 | matches = re.search(r' \d+$', file_name) 150 | if matches: 151 | start, end = matches.span() 152 | increment = str(int(matches.group())+1) + file_name[end:] 153 | file_name = file_name[:max(end-len(increment), start)].rstrip() 154 | new_file_name = "{0} {1}".format(file_name, increment) 155 | return new_file_name 156 | 157 | @staticmethod 158 | def log(message): 159 | sys.stderr.write('{0}\n'.format(message)) 160 | 161 | @staticmethod 162 | def normalize(value): 163 | if str(value).lower() in ("yes", "y", "tru", "true", "1"): return "True" 164 | if str(value).lower() in ("no", "n", "fal", "fals", "false", "0"): return "False" 165 | return value 166 | 167 | @staticmethod 168 | def settings(key, fallback=str()): 169 | bundle_id=os.getenv('the_archive_bundle_id') 170 | team_id=os.getenv('the_archive_team_id') 171 | plist=os.path.expanduser("~/Library/Group Containers/{0}.{1}.prefs/Library/Preferences/{0}.{1}.prefs.plist".format(team_id, bundle_id)) 172 | if os.path.exists(plist): 173 | data = Plist().readPlist(plist) 174 | for k, val in data.items(): 175 | if key == k: 176 | return val 177 | return fallback 178 | sys.stderr.write("Error: Cannot find the application settings, please verify the_archive_bundle_id.") 179 | sys.exit(0) 180 | 181 | @staticmethod 182 | def strJoin(*args): 183 | return str().join(args) 184 | 185 | @staticmethod 186 | def strReplace(text, replace_map, lowercase=True): 187 | for k in list(replace_map.keys()): 188 | text = text.replace(k, replace_map[k]) 189 | return text.lower() if lowercase else text 190 | 191 | @staticmethod 192 | def zettelIdExists(path, zettelId): 193 | err = 0 194 | file_list = list() 195 | try: 196 | file_list = os.listdir(path) 197 | except OSError as e: 198 | err = e.errno 199 | pass 200 | if err == 0: 201 | for filename in file_list: 202 | if filename.startswith(zettelId): 203 | return True 204 | return False 205 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alfred Workflow for The Archive 2 | 3 | This is an comprehensive workflow for The Archive that helps you work with your notes more efficiently. 4 | 5 | ## Table of Contents 6 | 7 | - [Installation](#installation) 8 | - [Searching Notes](#searching-notes) 9 | - [Searching Tasks](#searching-tasks) 10 | - [Searching Tags](#searching-tags) 11 | - [Random Notes](#random-notes) 12 | - [Creating Notes](#creating-notes) 13 | - [Templates](#templates) 14 | - [Importing URLs](#importing-urls) 15 | - [Importing Images](#importing-images) 16 | - [Text Manipulation](#text-manipulation) 17 | - [Configuration](#configuration) 18 | - [Documentation](#documentation) 19 | - [Changelog](#changelog) 20 | - [Credits](credits) 21 | 22 | ## Installation 23 | 24 | 1. Download [the latest release](https://github.com/pryley/alfred-the-archive/releases/latest/download/The.Archive.alfredworkflow) 25 | 2. Double-click the downloaded workflow to install in Alfred. 26 | 3. Install [Glance](https://apps.apple.com/us/app/glance-quick-look-plugin/id1513574319) from the App Store (optional, this allows you to Quickview markdown files) 27 | 4. Install [pandoc](https://pandoc.org/) with [Homebrew](https://brew.sh/) (optional, this allows you to import a webpage into a note) 28 | ```bash 29 | brew install pandoc 30 | ``` 31 | 32 | ## Searching Notes 33 | 34 | To search your notes, type `ar` along with a space, then enter your search query. 35 | 36 | ![](screenshots/ar.png) 37 | 38 | > **Tip:** You may change the [exact_match](#exact-match-exact_match) and [search_content](#search-content-search_content) options to configure how the workflow searches The Archive. 39 | 40 | ### Modifier keys 41 | 42 | There are three modifier keys that you can use with the search results: 43 | 44 | 1. **⇧ Shift:** Pressing this key will use Quicklook to preview the selected note. 45 | 46 | > **Note:** To view markdown files with Quicklook, you may need to [install Glance](#installation). 47 | 48 | 2. **⌥ Option:** Holding this key down as you press Enter will paste a wiki link of the selected note into the frontmost application (i.e. `[[title of the selected note]]`). 49 | 50 | 3. **⌘ Command:** Holding this key down as you press Enter will display the following "Actions" menu: 51 | 52 | ![](screenshots/ar_action_menu.png) 53 | 54 | ## Searching Tasks 55 | 56 | Tasks are Github-flavoured checkboxes: 57 | 58 | ```markdown 59 | - [x] This is a completed task 60 | - [ ] This is an uncompleted task 61 | ``` 62 | 63 | To search for tasks in your notes, type `artask` along with a space, then enter your search query. Pressing Enter on a task will toggle its status (checked/unchecked). 64 | 65 | ![](screenshots/artask.png) 66 | 67 | ### Modifier keys 68 | 69 | There are two modifier keys that you can use with tasks: 70 | 71 | 1. **⌥ Option:** Holding this key down as you press Enter will open the note containing the task in the default editor. 72 | 73 | 2. **⌘ Command:** Holding this key down as you press Enter will open the note containing the task in The Archive. 74 | 75 | ## Searching Tags 76 | 77 | To search the tags in your notes, type `artag` along with a space, then enter your search query. Pressing Enter on a tag will match all notes that contain the tag in The Archive. 78 | 79 | ![](screenshots/artag.png) 80 | 81 | > **Note:** Due to a limitation of the external link URL scheme that The Archive uses, it is not possible to pass the `#` symbol along with the tag name to The Archive. 82 | 83 | ### Modifier keys 84 | 85 | There is one modifier key that you can use with tags: 86 | 87 | 1. **⌘ Command:** Holding this key down as you press Enter will paste the selected tag into the frontmost application. 88 | 89 | ## Random Notes 90 | 91 | To display a random note in The Archive, type `arrandom` and press Enter. 92 | 93 | ![](screenshots/arrandom.png) 94 | 95 | ## Creating Notes 96 | 97 | To create a note, type `arnew` along with a space, then enter the title of the note and optionally some tags. If you use a template, the title you enter will fill the `{title}` placeholder, and any tags you enter will fill the `{tags}` placeholder. 98 | 99 | ![](screenshots/arnew.png) 100 | 101 | ### Modifier keys 102 | 103 | There are two modifier keys (and one modifier key combo) that you can use when creating a note without a template: 104 | 105 | 1. **⌥ Option:** Holding this key down as you press Enter will paste the current clipboard contents into the note below the tags. 106 | 107 | 2. **⌘ Command:** Holding this key down as you press Enter will either remove or add the Zettel ID to the note depending on whether or not you have enabled the "Use ID for empty file names" option in The Archive preferences. 108 | 109 | 3. **⌘ Command + ⌥ Option:** Holding these two keys down as you press Enter will both paste the current clipboard contents into the note below the tags, and remove or add the Zettel ID to the note depending on whether or not you have enabled the "Use ID for empty file names" option in The Archive preferences. 110 | 111 | ## Templates 112 | 113 | Templates are simply notes in The Archive that are tagged with `#template`. To create a note using a template, type `arnew` along with a space, enter the title of the note and optionally some tags, and then select the template that you wish to use. 114 | 115 | ![](screenshots/arnew_templates.png) 116 | 117 | > **Note:** The template tag must be used within the first 10 lines of the note else it will not be recognised as a template. 118 | 119 | > **Tip:** You may change the [template_tag](#template-tag-template_tag) option to set a custom template tag. 120 | 121 | You may use the following placeholders in your templates: 122 | 123 | - `{content}` This is the content of the clipboard if you have selected to paste it. 124 | - `{date}` This is the formatted today date. 125 | - `{tags}` These are the tags if provided. 126 | - `{title}` This is the title of your note. 127 | - `{zettel_id}` This is the Zettel ID of the note if used. 128 | 129 | Here is an example Template: 130 | 131 | ```markdown 132 | --- 133 | Title: [[{zettel_id}]] {title} 134 | Index: [[200615130000]] Application support 135 | Keywords: #support {tags} #template 136 | --- 137 | 138 | {content} 139 | ``` 140 | 141 | > **Tip:** You may change the [use_zettel_id_in_title](#use-zettel-id-in-title-use_zettel_id_in_title) option to configure whether or not the `{title}` placeholder contains the Zettel ID. To change the datetime format used in the `{date}` placeholder, change the [default_date_format](#default-date-format-default_date_format) option. 142 | 143 | ### Modifier keys 144 | 145 | There are three modifier keys (and one modifier key combo) that you can use with the search results: 146 | 147 | 1. **⇧ Shift:** Pressing this key will use Quicklook to preview the selected template. 148 | 149 | > **Note:** To view markdown files with Quicklook, you may need to [install Glance](#installation). 150 | 151 | 2. **⌥ Option:** Holding this key down as you press Enter will paste the current clipboard contents into the template's `{content}` placeholder. 152 | 153 | 3. **⌘ Command:** Holding this key down as you press Enter will either remove or add the Zettel ID to the note depending on whether or not you have enabled the "Use ID for empty file names" option in The Archive preferences. 154 | 4. **⌘ Command + ⌥ Option:** Holding these two keys down as you press Enter will both paste the current clipboard contents into the template's `{content}` placeholder, and remove or add the Zettel ID to the note depending on whether or not you have enabled the "Use ID for empty file names" option in The Archive preferences. 155 | 156 | ## Importing URLs 157 | 158 | To import the page content of a webpage into a note, type `arurl` along with a space and enter a valid URL beginning with `http(s)`. 159 | 160 | ![](screenshots/arurl.png) 161 | 162 | > **Note:** This action requires that you have [pandoc installed on your mac](#installation). Pandoc is a universal document converter and is used to convert the HTML of a webpage to Github-flavoured markdown. If you do not have pandoc installed, then only the URL will be copied into the note. 163 | 164 | ## Importing Images 165 | 166 | The workflow provides an **Add image to The Archive** File Action which allows you to import a JPG or PNG image into the Resources Subfolder of your notes directory. 167 | 168 | ![](screenshots/image_file_action.png) 169 | 170 | To use the File Action: 171 | 172 | 1. First you need to set your prefered "Selection Hotkey" for Actions. You can find this option on the `Features > Actions > General` tab in the Alfred Preferences. 173 | 2. Select the image in Finder and press the "Selection Hotkey" that you set in Alfred Preferences. 174 | 3. Type `add` and select the "Add image to The Archive" file action. 175 | 4. Paste the generated markdown link of the image into your note. 176 | 177 | ## Text Manipulation 178 | 179 | The workflow provides several hotkeys which allow you to perform basic text manipulation such as changing the heading levels of a line in your note, or marking multiple lines of text as a fenced code block using backticks. A hotkey is simply a combination of keys that you press together in order to perform an action. These hotkeys are specific to The Archive and will only work if The Archive is the front most application and in focus. 180 | 181 | To use these hotkeys, click on the line in your note that you wish to change and then press the hotkey. 182 | 183 | > **Note:** These hotkeys use the **⇧⌘L** keyboard shortcut that is provided by The Archive to select the current line of text. If you have mapped this keyboard shortcut to something else, then these hotkeys will not work. 184 | 185 | ### Hotkeys 186 | 187 | - **⌘ + 1**: Pressing this hotkey will change the line to a Heading 1 188 | - **⌘ + 2**: Pressing this hotkey will change the line to a Heading 2 189 | - **⌘ + 3**: Pressing this hotkey will change the line to a Heading 3 190 | - **⌘ + 4**: Pressing this hotkey will change the line to a Heading 4 191 | - **⌘ + 5**: Pressing this hotkey will change the line to a Heading 5 192 | - **⌘ + 6**: Pressing this hotkey will change the line to a Heading 6 193 | - **⌘ + `**: Pressing this hotkey will wrap the selected lines of text in backticks as a fenced code block 194 | 195 | ## Configuration 196 | 197 | To change the configuration of the workflow, type `arconfig` in Alfred. You can also view the help file for each highlighted option with Quicklook by pressing the **⇧ Shift** key. 198 | 199 | ![](screenshots/arconfig.png) 200 | 201 | > **Note:** To view markdown files with Quicklook, you may need to [install Glance](#installation). 202 | 203 | ### Default Date Format (`default_date_format`) 204 | 205 | > Default value: `%A, %d %B, %Y at %H:%M` 206 | 207 | This option defines the datetime format used for the `{date}` placeholder in your templates. 208 | 209 | Please refer to the [Python strftime reference](https://strftime.org/) for the available datetime variables. 210 | 211 | ### Default Zettel ID Format (`default_zettel_id_format`) 212 | 213 | > Default value: `%Y%m%d%H%M` 214 | 215 | This option defines the datetime format used for the generated Zettel ID and the `{zettel_id}` placeholder in your templates. 216 | 217 | Please refer to the [Python strftime reference](https://strftime.org/) for the available datetime variables. 218 | 219 | ### Exact Match (`exact_match`) 220 | 221 | > Default value: `False` 222 | 223 | This option defines if the search should match the exact search term (`True`) or the string (`False`). When the value is set to `True` it is possible to enhance the search term with wildcards. 224 | 225 | When set to `True`, searching for `Books` will match `Books` but not `Bookstore`. However, `Books*` will match both `Books` and `Bookstore`. 226 | 227 | When set to `False`, searching for `Books` will match `Books` as well as `Bookstore`. 228 | 229 | ### Prefer Filename to Title (`prefer_filename_to_title`) 230 | 231 | > Default value: `True` 232 | 233 | This option defines which value is used when matching a search result in The Archive (i.e. `thearchive://match/{value}`). 234 | 235 | When set to `True`, the note filename will be used. 236 | 237 | When set to `False`, the note title (if entered as `# Note Title`) will be used if it exists instead of the filename. 238 | 239 | ### Prefer Zettel ID Links (`prefer_zettel_id_links`) 240 | 241 | > Default value: `False` 242 | 243 | When set to `True`, the Zettel ID (if one exists) will be used as the link title in markdown and wiki links (i.e. `[[202006131200]]`). 244 | 245 | When set to `False`, the full note title will be used in markdown and wiki links (i.e. `[[202006131200 The Note Title]]`). 246 | 247 | ### Search Content (`search_content`) 248 | 249 | > Default value: `False` 250 | 251 | When set to `True`, both the filenames and note contents will be searched. 252 | 253 | When set to `False`, only the filenames will be searched. 254 | 255 | ### Search YAML Tags Only (`search_yaml_tags_only`) 256 | 257 | > Default value: `False` 258 | 259 | When set to `True`, tags will only be searched for in the YAML front matter. 260 | 261 | When set to `False`, tags will be searched for in the entire note. 262 | 263 | ### Template Tag (`template_tag`) 264 | 265 | > Default value: `#template` 266 | 267 | The template tag defines which notes are used as templates. Add the template tag somewhere in the first 10 lines of a note and it will be recognized as an available template when you create a note. 268 | 269 | ### The Archive Bundle ID (`the_archive_bundle_id`) 270 | 271 | > Default value: `de.zettelkasten.TheArchive` 272 | 273 | A bundle ID (or bundle identifier) uniquely identifies an application in Apple's ecosystem. This means that no two applications can have the same bundle identifier. 274 | 275 | This workflow uses the bundle identifier together with [the_archive_team_id](#the-archive-team-id-the_archive_team_id) to get the saved preferences of The Archive. 276 | 277 | This value should never need changing. 278 | 279 | ### The Archive Team ID (`the_archive_team_id`) 280 | 281 | > Default value: `FRMDA3XRGC` 282 | 283 | A team ID (or team identifier) is generated by Apple and uniquely identifies the developer of an application in Apple's ecosystem. 284 | 285 | This workflow uses the team identifier together with [the_archive_bundle_id](#the-archive-bundle-id-the_archive_bundle_id) to get the saved preferences of The Archive. 286 | 287 | This value should never need changing. 288 | 289 | ### Use Zettel ID in Title (`use_zettel_id_in_title`) 290 | 291 | > Default value: `False` 292 | 293 | When set to `True`, the Zettel ID will be included in the `{title}` placeholder of your templates. 294 | 295 | When set to `False`, the Zettel ID will not be included in the `{title}` placeholder of your templates. 296 | 297 | ## Documentation 298 | 299 | You may view this README.md file at any time by typing `arhelp` in Alfred. 300 | 301 | ![](screenshots/arhelp.png) 302 | 303 | ## Changelog 304 | 305 | See: [Releases](https://github.com/pryley/alfred-the-archive/releases) 306 | 307 | ## Credits 308 | 309 | This workflow was created by [Paul Ryley](https://github.com/pryley/). Special thanks to [Acidham](https://github.com/Acidham) author of [Alfred Markdown Notes](https://github.com/Acidham/alfred-markdown-notes) which was the inspiration for this workflow. 310 | 311 | ![](screenshots/ardonate.png) 312 | 313 | ## License 314 | 315 | The MIT License (MIT). 316 | -------------------------------------------------------------------------------- /Notes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | from Alfred import Tools 5 | from collections import Counter, OrderedDict 6 | from QuerySplitter import QuerySplitter 7 | from unicodedata import normalize 8 | import os 9 | import re 10 | import sys 11 | 12 | class Notes(object): 13 | 14 | CHAR_REPLACEMENT_MAP = { 15 | '/': '-', 16 | '\\': '-', 17 | ':': '-', 18 | ',': '', 19 | '#': '-' 20 | } 21 | 22 | FALLBACK_CONTENT = "{tags}\n\n{content}" 23 | 24 | REPL_MAP = { 25 | '[': '', 26 | ']': ' ', 27 | '(': '', 28 | ')': ' ', 29 | '\n': ' ', 30 | '*': ' ', 31 | ',': ' ', 32 | '.': ' ', 33 | '-': ' ', 34 | ':': ' ', 35 | '?': ' ', 36 | '!': ' ' 37 | } 38 | 39 | UMLAUT_REPL_MAP = { 40 | '\xc3\x84': 'Ae', # Ä 41 | '\xc3\x88': 'e', # È 42 | '\xc3\x96': 'Oe', # Ö 43 | '\xc3\x9c': 'Ue', # Ü 44 | '\xc3\x9f': 'ss', # ß 45 | '\xc3\xa4': 'ae', # ä 46 | '\xc3\xa5': 'as', # å 47 | '\xc3\xb6': 'oe', # ö 48 | '\xc3\xbc': 'ue', # ü 49 | } 50 | 51 | def __init__(self): 52 | self.allowed_extensions = self._getAllowedExtensions() 53 | self.default_date_format = os.getenv('default_date_format') 54 | self.default_extension = self._getDefaultExtension() 55 | self.exact_match = True if os.getenv('exact_match') == 'True' else False 56 | self.path = Tools.getNotesPath() 57 | self.prefer_filename_to_title = True if os.getenv('prefer_filename_to_title') == 'True' else False 58 | self.prefer_zettel_id_links = True if os.getenv('prefer_zettel_id_links') == 'True' else False 59 | self.search_content = True if os.getenv('search_content') == 'True' else False 60 | self.search_yaml_tags_only = True if os.getenv('search_yaml_tags_only') == 'True' else False 61 | self.template_tag = os.getenv('template_tag') 62 | self.use_zettel_id = Tools.settings('isUsingIDForNewFiles', True) 63 | self.use_zettel_id_in_title = True if os.getenv('use_zettel_id_in_title') == 'True' else False 64 | 65 | @staticmethod 66 | def _getAllowedExtensions(): 67 | extensions = Tools.settings('fileExtensions', ['md','txt']) 68 | allowed_extensions = [Notes.normalizeExt(ext) for ext in extensions] 69 | return tuple(allowed_extensions) 70 | 71 | @staticmethod 72 | def _getDefaultExtension(): 73 | ext = Tools.settings('fileExtension', 'md') 74 | return Notes.normalizeExt(ext) 75 | 76 | def getAllowedExtensions(self): 77 | return self.allowed_extensions 78 | 79 | def getDefaultExtension(self): 80 | return self.default_extension 81 | 82 | @staticmethod 83 | def normalizeExt(ext): 84 | return ext if '.' in ext else str().join(['.', ext]) 85 | 86 | def useZettelId(self): 87 | return self.use_zettel_id 88 | 89 | class Note(Notes): 90 | 91 | def __init__(self, title, template_path=str(), tags=str(), content=str(), zettel_id=str()): 92 | super(Note, self).__init__() 93 | self.tags = tags 94 | self.content = content 95 | self.title = "{0} {1}".format(zettel_id, title).strip() if self.use_zettel_id_in_title else title 96 | self.zettel_id = zettel_id 97 | self.note_path = self.getTargetFilePath(self.normalizeFilename("{0} {1}".format(zettel_id, title))) 98 | self.template_path = template_path 99 | 100 | def createNote(self): 101 | try: 102 | with open(self.note_path, "w+") as f: 103 | file_content = self.readTemplate( 104 | content=self.content, 105 | date=Tools.getTodayDate(), 106 | tags=self.tags, 107 | title=self.title, 108 | zettel_id=self.zettel_id, 109 | ) 110 | f.write(file_content) 111 | return self.note_path 112 | except Exception as e: 113 | sys.stderr.write(e) 114 | 115 | def getTargetFilePath(self, file_name): 116 | file_name = file_name.rstrip().lstrip() 117 | file_path = os.path.join(self.path, file_name + self.default_extension) 118 | if os.path.isfile(file_path): 119 | new_file_name = Tools.increment(file_name) 120 | return self.getTargetFilePath(new_file_name) 121 | file_path = os.path.join(self.path, file_name + self.default_extension) 122 | return file_path 123 | 124 | def normalizeFilename(self, filename): 125 | self.CHAR_REPLACEMENT_MAP.update(self.UMLAUT_REPL_MAP) 126 | return Tools.strReplace(filename, self.CHAR_REPLACEMENT_MAP, lowercase=False) 127 | 128 | def readTemplate(self, **kwargs): 129 | if '#' not in self.template_tag or self.template_tag == str(): 130 | self.template_tag = '#template' 131 | if os.path.exists(self.template_path): 132 | with open(self.template_path, "r") as file: 133 | content = file.read() 134 | else: 135 | content = self.FALLBACK_CONTENT 136 | content = content.replace(self.template_tag, '') 137 | for k, v in list(kwargs.items()): 138 | content = content.replace('{' + k + '}', v) 139 | return content 140 | 141 | class Search(Notes): 142 | 143 | def __init__(self): 144 | super(Search, self).__init__() 145 | 146 | def _getFileContent(self, file_path): 147 | if file_path.endswith(self.allowed_extensions): 148 | with open(file_path, 'r') as c: 149 | content = c.read() 150 | else: 151 | content = str() 152 | return normalize('NFD', content) 153 | 154 | def _match(self, search_terms, content, operator): 155 | content = content.lower() 156 | content = Tools.strReplace(content, self.REPL_MAP) 157 | word_list = content.split(' ') 158 | word_list = [Tools.chop(w, '#') for w in word_list] 159 | search_terms = [s.lower() for s in search_terms] 160 | match = False 161 | matches = list() 162 | for st in search_terms: 163 | search_str = st.replace('*', str()) 164 | # search if search term contains a whitespace 165 | if ' ' in st: 166 | regexp = re.compile(r'({0})'.format(st), re.I) 167 | match = True if len(re.findall(regexp, content)) > 0 else False 168 | # search if wildcard search in the end 169 | elif st.endswith('*'): 170 | match_list = [x for x in word_list if x.startswith(search_str)] 171 | match = True if len(match_list) > 0 else False 172 | # search if wildcard search in front 173 | elif st.startswith('*'): 174 | match_list = [x for x in word_list if x.endswith(search_str)] 175 | match = True if len(match_list) > 0 else False 176 | # search if exact match is true 177 | elif self.exact_match: 178 | match = True if search_str in word_list else False 179 | # search with exact match is false 180 | else: 181 | match = True if search_str in str(word_list) else False 182 | matches.append(match) 183 | match = all(matches) if operator == 'AND' else any(matches) 184 | return match 185 | 186 | def getFileMeta(self, path, item): 187 | file_stats = os.stat(path) 188 | switch = { 189 | 'ctime': file_stats.st_birthtime, 190 | 'mtime': file_stats.st_mtime, 191 | 'size': file_stats.st_size 192 | } 193 | return switch[item] 194 | 195 | def getFilesListSorted(self, reverse=True): 196 | err = 0 197 | file_list = list() 198 | try: 199 | file_list = os.listdir(self.path) 200 | except OSError as e: 201 | err = e.errno 202 | pass 203 | if err == 0: 204 | seq = list() 205 | for filename in file_list: 206 | file_path = os.path.join(self.path, filename) 207 | not (filename.startswith('.')) and filename.endswith(self.allowed_extensions) and seq.append({ 208 | 'filename': filename, 209 | 'path': file_path, 210 | 'title': self.getNoteTitle(file_path), 211 | 'ctime': self.getFileMeta(file_path, 'ctime'), 212 | 'mtime': self.getFileMeta(file_path, 'mtime'), 213 | 'size': self.getFileMeta(file_path, 'size') 214 | }) 215 | sorted_file_list = sorted(seq, key=lambda k: k['mtime'], reverse=reverse) 216 | return sorted_file_list 217 | 218 | def getNoteFilename(self, file_path): 219 | file_basename = os.path.basename(file_path) 220 | return file_basename.rsplit('.', 1)[0] 221 | 222 | def getNoteLinkTitle(self, path): 223 | title = self.getNoteTitle(path) 224 | if self.prefer_zettel_id_links: 225 | qs = QuerySplitter(title) 226 | if qs.zettel_id: 227 | title = qs.zettel_id 228 | return title 229 | 230 | def getNoteTitle(self, path): 231 | content = self._getFileContent(path) 232 | title = self.getNoteFilename(path) 233 | if not self.prefer_filename_to_title: 234 | obj = re.search(r'^#{1}\s{1}(.*)', content, re.MULTILINE | re.UNICODE) 235 | if obj is not None: 236 | title = obj.group(1) if len(re.findall(r'\{.*\}', obj.group(1))) == 0 else title 237 | return title 238 | 239 | def getSearchConfig(self, query): 240 | if '&' in list(query): 241 | search_terms = query.split('&') 242 | search_type = 'and' 243 | elif '|' in list(query): 244 | search_terms = query.split('|') 245 | search_type = 'or' 246 | elif query == str(): 247 | search_terms = list() 248 | search_type = 'or' 249 | else: 250 | search_terms = [query] 251 | search_type = 'or' 252 | return search_terms, search_type 253 | 254 | def getTemplateTag(self): 255 | tt = Tools.getEnv('template_tag') 256 | if '#' not in tt or tt == str(): 257 | tt = '#template' 258 | return tt 259 | 260 | def isNoteTagged(self, file_path, tag): 261 | match = False 262 | with open(file_path, 'r') as c: 263 | lines = c.readlines()[0:10] 264 | for l in lines: 265 | match_obj = re.search(tag, l, re.IGNORECASE) 266 | if match_obj: 267 | match = True 268 | break 269 | return match 270 | 271 | def notes(self, search_terms, search_type): 272 | file_list = self.getFilesListSorted() 273 | search_terms = [normalize('NFD', s) for s in search_terms] 274 | new_list = list() 275 | if file_list is not None: 276 | for file in file_list: 277 | title = self.getNoteTitle(file['path']) 278 | if (search_type == 'and' and self._match(search_terms, title, 'AND')) or (search_type == 'or' and self._match(search_terms, title, 'OR')): 279 | new_list.append(file) 280 | elif self.search_content: 281 | content = self._getFileContent(file['path']) 282 | if content != str() and (search_type == 'and' and self._match(search_terms, content, 'AND')) or (search_type == 'or' and self._match(search_terms, content, 'OR')): 283 | new_list.append(file) 284 | return new_list 285 | 286 | def tags(self, tag, sort_by='tag', reverse=False): 287 | i = {'tag': 0, 'count': 1} 288 | tag = normalize('NFD', tag) 289 | matches = list() 290 | sorted_file_list = self.getFilesListSorted() 291 | regex = re.compile(r"#{1}([\w-]+)\s?", re.I) if tag == '' else re.compile(r'#{1}(' + tag + r'[\w-]*)\s?', re.I | re.UNICODE) 292 | for f in sorted_file_list: 293 | content = self._getFileContent(f['path']) 294 | if content != str(): 295 | if self.search_yaml_tags_only: 296 | match_obj = re.search(r"\b.*[\s\S](-{3,})", content, re.IGNORECASE | re.UNICODE) 297 | if match_obj: 298 | r = match_obj.group(0) 299 | results = re.findall(regex, r) 300 | matches.extend(results) 301 | else: 302 | results = re.findall(regex, content) 303 | matches.extend(results) 304 | counted_matches = Counter([v.lower() for v in matches]) 305 | sorted_matches = OrderedDict(sorted(list(counted_matches.items()), key=lambda x: x[i[sort_by]], reverse=reverse)) 306 | return sorted_matches 307 | 308 | def tasks(self, todo): 309 | matches = list() 310 | sorted_file_list = self.getFilesListSorted() 311 | regexPending = re.compile(r'[-|\*] {1}\[ \] {1}(.+)', re.I) if todo == '' else re.compile(r'[-|\*] {1}\[ \] {1}(.*' + todo + '.*)', re.I) 312 | regexDone = re.compile(r'[-|\*] {1}\[x\] {1}(.+)', re.I) if todo == '' else re.compile(r'[-|\*] {1}\[x\] {1}(.*' + todo + '.*)', re.I) 313 | for f in sorted_file_list: 314 | content = self._getFileContent(f['path']) 315 | if content != str(): 316 | results = re.findall(regexPending, content) 317 | for i in results: 318 | r_dict = { 319 | 'path': f['path'], 320 | 'todo': i, 321 | 'status': 'pending', 322 | 'filename': f['filename'], 323 | 'title': f['title'], 324 | 'mtime': self.getFileMeta(f['path'], 'mtime'), 325 | 'ctime': self.getFileMeta(f['path'], 'ctime') 326 | } 327 | matches.append(r_dict) 328 | results = re.findall(regexDone, content) 329 | for i in results: 330 | r_dict = { 331 | 'path': f['path'], 332 | 'todo': i, 333 | 'status': 'done', 334 | 'filename': f['filename'], 335 | 'title': f['title'], 336 | 'mtime': self.getFileMeta(f['path'], 'mtime'), 337 | 'ctime': self.getFileMeta(f['path'], 'ctime') 338 | } 339 | matches.append(r_dict) 340 | ret_list_dict = sorted(matches, key=lambda k: k['ctime'], reverse=False) 341 | return ret_list_dict 342 | 343 | def templates(self): 344 | template_tag = self.getTemplateTag() 345 | file_list = self.getFilesListSorted() 346 | templates = list() 347 | if file_list is not None: 348 | for file in file_list: 349 | if self.isNoteTagged(file['path'], template_tag): 350 | templates.append(file) 351 | return templates 352 | 353 | def zettelIdExists(self, zettelId): 354 | err = 0 355 | file_list = list() 356 | try: 357 | file_list = os.listdir(self.path) 358 | except OSError as e: 359 | err = e.errno 360 | pass 361 | if err == 0: 362 | for filename in file_list: 363 | if filename.startswith(zettelId): 364 | return True 365 | return False 366 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.apple.alfred.workflow.the-archive 7 | category 8 | Productivity 9 | connections 10 | 11 | 06634071-A34F-47EA-9A93-224F1E437E99 12 | 13 | 14 | destinationuid 15 | D7F05A73-355B-4C77-A4F8-F301CF68FB9A 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | vitoclose 21 | 22 | 23 | 24 | destinationuid 25 | FA40A7DB-25B4-464C-B269-EC046612AD60 26 | modifiers 27 | 0 28 | modifiersubtext 29 | 30 | vitoclose 31 | 32 | 33 | 34 | 0BC841DD-23D7-4621-BB77-3C6851C20031 35 | 36 | 37 | destinationuid 38 | 97B0EE32-A8A1-405E-B0F2-C459AC7FC3E3 39 | modifiers 40 | 0 41 | modifiersubtext 42 | 43 | vitoclose 44 | 45 | 46 | 47 | 0F5540E1-5999-4328-9C24-3C9E18E2746D 48 | 49 | 50 | destinationuid 51 | E1BE1374-4C3C-483D-B093-3AFB164AA55A 52 | modifiers 53 | 0 54 | modifiersubtext 55 | 56 | vitoclose 57 | 58 | 59 | 60 | 0F836984-A230-4C9E-A376-2A6F54239A8D 61 | 62 | 63 | destinationuid 64 | ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B 65 | modifiers 66 | 0 67 | modifiersubtext 68 | 69 | vitoclose 70 | 71 | 72 | 73 | 13D7AF95-E68C-4207-AD54-532455FFBC15 74 | 75 | 76 | destinationuid 77 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 78 | modifiers 79 | 0 80 | modifiersubtext 81 | 82 | vitoclose 83 | 84 | 85 | 86 | 1AD1E2CF-FCB9-45E5-B8F2-9C6B0CEAABD6 87 | 88 | 89 | destinationuid 90 | D2AD3BCE-73FA-4344-B003-A57E66E4AC6B 91 | modifiers 92 | 0 93 | modifiersubtext 94 | 95 | sourceoutputuid 96 | 6D724BD9-BEF7-4D28-8DCC-A594E968CD3E 97 | vitoclose 98 | 99 | 100 | 101 | destinationuid 102 | A4A95B3D-BE6A-45BC-A53B-74984F4F48A7 103 | modifiers 104 | 0 105 | modifiersubtext 106 | 107 | sourceoutputuid 108 | 1ADF607C-65D9-4B0E-B580-428737D4FE3F 109 | vitoclose 110 | 111 | 112 | 113 | destinationuid 114 | B45C99C4-5814-48E9-A8C4-426F939F7335 115 | modifiers 116 | 0 117 | modifiersubtext 118 | 119 | sourceoutputuid 120 | 03A97A98-84AF-47FA-BD7A-F5BD9090159F 121 | vitoclose 122 | 123 | 124 | 125 | destinationuid 126 | D0A0BB4A-D8DC-4463-A00F-06ABF17CF7F3 127 | modifiers 128 | 0 129 | modifiersubtext 130 | 131 | sourceoutputuid 132 | 3961D0C5-8015-4EDE-8753-F201EB4B11C1 133 | vitoclose 134 | 135 | 136 | 137 | destinationuid 138 | EB8A1BFE-4152-4203-A6B8-DAA827BA4932 139 | modifiers 140 | 0 141 | modifiersubtext 142 | 143 | sourceoutputuid 144 | 325682B6-E189-423E-A2E9-2D12608FDA53 145 | vitoclose 146 | 147 | 148 | 149 | 22568BCE-A99B-499A-B22B-D125B36C3A97 150 | 151 | 152 | destinationuid 153 | FD181211-B1A6-463B-AF31-28A941B28F2E 154 | modifiers 155 | 0 156 | modifiersubtext 157 | 158 | vitoclose 159 | 160 | 161 | 162 | 28072C72-6F5F-49D3-9C79-F39D03C75A11 163 | 164 | 165 | destinationuid 166 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 167 | modifiers 168 | 0 169 | modifiersubtext 170 | 171 | vitoclose 172 | 173 | 174 | 175 | 3078B7FC-DAD0-48C1-938B-E2C5102800D8 176 | 177 | 178 | destinationuid 179 | A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9 180 | modifiers 181 | 0 182 | modifiersubtext 183 | 184 | vitoclose 185 | 186 | 187 | 188 | 341A03B4-7E79-4AD7-A347-AF17C634D4FF 189 | 190 | 191 | destinationuid 192 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 193 | modifiers 194 | 0 195 | modifiersubtext 196 | 197 | vitoclose 198 | 199 | 200 | 201 | 3666E55C-5EA1-4C6A-9565-22A55CE17403 202 | 203 | 204 | destinationuid 205 | C767AF6B-DF2C-40A1-8F23-916EDE028F7F 206 | modifiers 207 | 0 208 | modifiersubtext 209 | 210 | vitoclose 211 | 212 | 213 | 214 | 42848B7A-9D43-4C79-9E97-A8990FACBAE7 215 | 216 | 217 | destinationuid 218 | FA40A7DB-25B4-464C-B269-EC046612AD60 219 | modifiers 220 | 0 221 | modifiersubtext 222 | 223 | vitoclose 224 | 225 | 226 | 227 | 47A8B5B3-11A9-4177-A3DA-18CDE6C4F71D 228 | 229 | 230 | destinationuid 231 | 629E7681-4B3B-44F8-931C-617775EE6CFA 232 | modifiers 233 | 0 234 | modifiersubtext 235 | 236 | vitoclose 237 | 238 | 239 | 240 | 524CFE69-2161-4618-BC65-7D380B0B3EAD 241 | 242 | 243 | destinationuid 244 | 22568BCE-A99B-499A-B22B-D125B36C3A97 245 | modifiers 246 | 0 247 | modifiersubtext 248 | 249 | vitoclose 250 | 251 | 252 | 253 | destinationuid 254 | 8A5F7A4E-FC3A-466E-A53A-38313E9F8022 255 | modifiers 256 | 524288 257 | modifiersubtext 258 | 259 | vitoclose 260 | 261 | 262 | 263 | destinationuid 264 | D6A73E77-7D81-45B7-AC0B-B6E59D5B94DD 265 | modifiers 266 | 1048576 267 | modifiersubtext 268 | 269 | vitoclose 270 | 271 | 272 | 273 | 5679BD15-58A7-4FCF-9737-E6B573CE4779 274 | 275 | 276 | destinationuid 277 | 9C2A4DF6-ECF8-45B0-9980-FBE6B1DE2739 278 | modifiers 279 | 0 280 | modifiersubtext 281 | 282 | sourceoutputuid 283 | 8D1F8B77-D912-457F-AB03-DA333DAA4E8B 284 | vitoclose 285 | 286 | 287 | 288 | destinationuid 289 | C9B46D25-C13C-4CBC-A087-787CB09B06E5 290 | modifiers 291 | 0 292 | modifiersubtext 293 | 294 | sourceoutputuid 295 | 8D1F8B77-D912-457F-AB03-DA333DAA4E8B 296 | vitoclose 297 | 298 | 299 | 300 | destinationuid 301 | B6D96F39-3BF6-4663-BF58-33CD36A2433D 302 | modifiers 303 | 0 304 | modifiersubtext 305 | 306 | vitoclose 307 | 308 | 309 | 310 | 629E7681-4B3B-44F8-931C-617775EE6CFA 311 | 312 | 313 | destinationuid 314 | B78F0AC4-5704-4E41-A5C5-41D7EF829577 315 | modifiers 316 | 0 317 | modifiersubtext 318 | 319 | vitoclose 320 | 321 | 322 | 323 | destinationuid 324 | 06634071-A34F-47EA-9A93-224F1E437E99 325 | modifiers 326 | 524288 327 | modifiersubtext 328 | 329 | vitoclose 330 | 331 | 332 | 333 | destinationuid 334 | 3666E55C-5EA1-4C6A-9565-22A55CE17403 335 | modifiers 336 | 1048576 337 | modifiersubtext 338 | 339 | vitoclose 340 | 341 | 342 | 343 | 657FD06E-6635-4C54-88C2-8FF658370FD7 344 | 345 | 346 | destinationuid 347 | DBE958B2-368A-48F9-A8AB-1DC9FC300B27 348 | modifiers 349 | 0 350 | modifiersubtext 351 | 352 | vitoclose 353 | 354 | 355 | 356 | 65FB1EF4-D09E-4070-BB2E-E3FF6FB331EA 357 | 358 | 359 | destinationuid 360 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 361 | modifiers 362 | 0 363 | modifiersubtext 364 | 365 | vitoclose 366 | 367 | 368 | 369 | 699C78CF-86C9-47FA-A077-DB7462FDE43F 370 | 371 | 372 | destinationuid 373 | ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B 374 | modifiers 375 | 0 376 | modifiersubtext 377 | 378 | vitoclose 379 | 380 | 381 | 382 | 6B5486CD-8FE6-493A-AB5E-DC1E63F6979F 383 | 384 | 385 | destinationuid 386 | C60A62FF-9B59-4C3C-99F3-807373F2125E 387 | modifiers 388 | 0 389 | modifiersubtext 390 | 391 | vitoclose 392 | 393 | 394 | 395 | 724B20C2-2A71-4470-AA68-E9B53C3E089D 396 | 397 | 398 | destinationuid 399 | DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D 400 | modifiers 401 | 0 402 | modifiersubtext 403 | 404 | vitoclose 405 | 406 | 407 | 408 | 82C3724E-6E6D-4282-A8D5-F528A6D5A0AE 409 | 410 | 411 | destinationuid 412 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 413 | modifiers 414 | 0 415 | modifiersubtext 416 | 417 | vitoclose 418 | 419 | 420 | 421 | 8C6B9363-12F2-4E71-8CE7-D1D9777F05C3 422 | 423 | 424 | destinationuid 425 | BC34D5F9-85CA-4E33-A951-941FE061EEE8 426 | modifiers 427 | 0 428 | modifiersubtext 429 | 430 | vitoclose 431 | 432 | 433 | 434 | 966EB023-178A-428E-B2CB-576954E4A33A 435 | 436 | 437 | destinationuid 438 | 524CFE69-2161-4618-BC65-7D380B0B3EAD 439 | modifiers 440 | 0 441 | modifiersubtext 442 | 443 | vitoclose 444 | 445 | 446 | 447 | 97B0EE32-A8A1-405E-B0F2-C459AC7FC3E3 448 | 449 | 450 | destinationuid 451 | B6D96F39-3BF6-4663-BF58-33CD36A2433D 452 | modifiers 453 | 0 454 | modifiersubtext 455 | 456 | sourceoutputuid 457 | CFCFC687-F6EB-434F-B483-6B71BE71AF5B 458 | vitoclose 459 | 460 | 461 | 462 | destinationuid 463 | C60A62FF-9B59-4C3C-99F3-807373F2125E 464 | modifiers 465 | 0 466 | modifiersubtext 467 | 468 | vitoclose 469 | 470 | 471 | 472 | 9C2A4DF6-ECF8-45B0-9980-FBE6B1DE2739 473 | 474 | 475 | destinationuid 476 | 0BC841DD-23D7-4621-BB77-3C6851C20031 477 | modifiers 478 | 0 479 | modifiersubtext 480 | 481 | vitoclose 482 | 483 | 484 | 485 | A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4 486 | 487 | 488 | destinationuid 489 | 6B5486CD-8FE6-493A-AB5E-DC1E63F6979F 490 | modifiers 491 | 0 492 | modifiersubtext 493 | 494 | vitoclose 495 | 496 | 497 | 498 | A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9 499 | 500 | 501 | destinationuid 502 | CCFB27EC-FE2A-4853-92F9-66D2E16EC154 503 | modifiers 504 | 0 505 | modifiersubtext 506 | 507 | vitoclose 508 | 509 | 510 | 511 | A4A95B3D-BE6A-45BC-A53B-74984F4F48A7 512 | 513 | 514 | destinationuid 515 | FA40A7DB-25B4-464C-B269-EC046612AD60 516 | modifiers 517 | 0 518 | modifiersubtext 519 | 520 | vitoclose 521 | 522 | 523 | 524 | A73C0944-0E7B-483F-BC14-1A0089887B05 525 | 526 | 527 | destinationuid 528 | FA40A7DB-25B4-464C-B269-EC046612AD60 529 | modifiers 530 | 0 531 | modifiersubtext 532 | 533 | vitoclose 534 | 535 | 536 | 537 | ABB1A2DA-ECDB-4ECF-AAAE-EACF4246706D 538 | 539 | 540 | destinationuid 541 | A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4 542 | modifiers 543 | 0 544 | modifiersubtext 545 | 546 | vitoclose 547 | 548 | 549 | 550 | B45C99C4-5814-48E9-A8C4-426F939F7335 551 | 552 | 553 | destinationuid 554 | FA40A7DB-25B4-464C-B269-EC046612AD60 555 | modifiers 556 | 0 557 | modifiersubtext 558 | 559 | vitoclose 560 | 561 | 562 | 563 | B58A48B9-E9D2-46BA-B2FC-8D52D0002AFD 564 | 565 | 566 | destinationuid 567 | 524CFE69-2161-4618-BC65-7D380B0B3EAD 568 | modifiers 569 | 0 570 | modifiersubtext 571 | 572 | vitoclose 573 | 574 | 575 | 576 | B78F0AC4-5704-4E41-A5C5-41D7EF829577 577 | 578 | 579 | destinationuid 580 | D6A73E77-7D81-45B7-AC0B-B6E59D5B94DD 581 | modifiers 582 | 0 583 | modifiersubtext 584 | 585 | sourceoutputuid 586 | B649ABA2-9104-4A0B-90FA-B1207CE605E5 587 | vitoclose 588 | 589 | 590 | 591 | destinationuid 592 | CE0C3E3D-3480-4860-8AEF-D91987553D48 593 | modifiers 594 | 0 595 | modifiersubtext 596 | 597 | vitoclose 598 | 599 | 600 | 601 | BE57B8E8-5E6A-43EC-8087-342FE3342B6C 602 | 603 | 604 | destinationuid 605 | CB491715-463C-4A1F-BF00-4EF95002AF65 606 | modifiers 607 | 0 608 | modifiersubtext 609 | 610 | vitoclose 611 | 612 | 613 | 614 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 615 | 616 | 617 | destinationuid 618 | 51A1F4B9-D0F3-40BD-AB30-22AF874BA1A9 619 | modifiers 620 | 0 621 | modifiersubtext 622 | 623 | vitoclose 624 | 625 | 626 | 627 | C767AF6B-DF2C-40A1-8F23-916EDE028F7F 628 | 629 | 630 | destinationuid 631 | 657FD06E-6635-4C54-88C2-8FF658370FD7 632 | modifiers 633 | 0 634 | modifiersubtext 635 | 636 | vitoclose 637 | 638 | 639 | 640 | C813B26C-8583-4087-9E6E-1FAC323A7F0F 641 | 642 | 643 | destinationuid 644 | 59FC67F4-40A5-440E-B854-0B65823BD164 645 | modifiers 646 | 0 647 | modifiersubtext 648 | 649 | vitoclose 650 | 651 | 652 | 653 | CB491715-463C-4A1F-BF00-4EF95002AF65 654 | 655 | 656 | destinationuid 657 | C60A62FF-9B59-4C3C-99F3-807373F2125E 658 | modifiers 659 | 0 660 | modifiersubtext 661 | 662 | vitoclose 663 | 664 | 665 | 666 | destinationuid 667 | D7F05A73-355B-4C77-A4F8-F301CF68FB9A 668 | modifiers 669 | 1048576 670 | modifiersubtext 671 | 672 | vitoclose 673 | 674 | 675 | 676 | CCFB27EC-FE2A-4853-92F9-66D2E16EC154 677 | 678 | 679 | destinationuid 680 | D4A81EE0-15F4-4F07-B5B6-FD9E7646EB3A 681 | modifiers 682 | 0 683 | modifiersubtext 684 | 685 | vitoclose 686 | 687 | 688 | 689 | D0A0BB4A-D8DC-4463-A00F-06ABF17CF7F3 690 | 691 | 692 | destinationuid 693 | C813B26C-8583-4087-9E6E-1FAC323A7F0F 694 | modifiers 695 | 0 696 | modifiersubtext 697 | 698 | vitoclose 699 | 700 | 701 | 702 | D276EC74-1F27-4BA5-97A8-A4E9D1020D2A 703 | 704 | 705 | destinationuid 706 | EF0769B1-0BDA-4D96-B640-1FA8EB1FD7BB 707 | modifiers 708 | 0 709 | modifiersubtext 710 | 711 | vitoclose 712 | 713 | 714 | 715 | D2AD3BCE-73FA-4344-B003-A57E66E4AC6B 716 | 717 | 718 | destinationuid 719 | 8A5F7A4E-FC3A-466E-A53A-38313E9F8022 720 | modifiers 721 | 0 722 | modifiersubtext 723 | 724 | vitoclose 725 | 726 | 727 | 728 | D4A81EE0-15F4-4F07-B5B6-FD9E7646EB3A 729 | 730 | 731 | destinationuid 732 | D276EC74-1F27-4BA5-97A8-A4E9D1020D2A 733 | modifiers 734 | 0 735 | modifiersubtext 736 | 737 | vitoclose 738 | 739 | 740 | 741 | D6A73E77-7D81-45B7-AC0B-B6E59D5B94DD 742 | 743 | 744 | destinationuid 745 | C60A62FF-9B59-4C3C-99F3-807373F2125E 746 | modifiers 747 | 0 748 | modifiersubtext 749 | 750 | vitoclose 751 | 752 | 753 | 754 | D7113CA2-175F-4D98-B738-A732E4826D02 755 | 756 | 757 | destinationuid 758 | 42848B7A-9D43-4C79-9E97-A8990FACBAE7 759 | modifiers 760 | 0 761 | modifiersubtext 762 | 763 | vitoclose 764 | 765 | 766 | 767 | DBE958B2-368A-48F9-A8AB-1DC9FC300B27 768 | 769 | 770 | destinationuid 771 | 1AD1E2CF-FCB9-45E5-B8F2-9C6B0CEAABD6 772 | modifiers 773 | 0 774 | modifiersubtext 775 | 776 | vitoclose 777 | 778 | 779 | 780 | DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D 781 | 782 | 783 | destinationuid 784 | 5679BD15-58A7-4FCF-9737-E6B573CE4779 785 | modifiers 786 | 0 787 | modifiersubtext 788 | 789 | vitoclose 790 | 791 | 792 | 793 | E0CED2B6-51DD-4178-B6BF-5FC59F6EE725 794 | 795 | 796 | destinationuid 797 | 699C78CF-86C9-47FA-A077-DB7462FDE43F 798 | modifiers 799 | 0 800 | modifiersubtext 801 | 802 | vitoclose 803 | 804 | 805 | 806 | E83305CB-1BAA-457E-93A8-0B9C7689D3C7 807 | 808 | 809 | destinationuid 810 | 629E7681-4B3B-44F8-931C-617775EE6CFA 811 | modifiers 812 | 0 813 | modifiersubtext 814 | 815 | vitoclose 816 | 817 | 818 | 819 | EB8A1BFE-4152-4203-A6B8-DAA827BA4932 820 | 821 | 822 | destinationuid 823 | 42489888-94A8-4578-A4CB-BCAE3F2D7339 824 | modifiers 825 | 0 826 | modifiersubtext 827 | 828 | vitoclose 829 | 830 | 831 | 832 | ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B 833 | 834 | 835 | destinationuid 836 | A8B79535-E3CC-4A12-B1A0-CBE9634E5804 837 | modifiers 838 | 0 839 | modifiersubtext 840 | 841 | vitoclose 842 | 843 | 844 | 845 | EF0769B1-0BDA-4D96-B640-1FA8EB1FD7BB 846 | 847 | 848 | destinationuid 849 | C60A62FF-9B59-4C3C-99F3-807373F2125E 850 | modifiers 851 | 0 852 | modifiersubtext 853 | 854 | vitoclose 855 | 856 | 857 | 858 | F2AF7DA9-9371-485E-B037-DF138D6379C1 859 | 860 | 861 | destinationuid 862 | A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9 863 | modifiers 864 | 0 865 | modifiersubtext 866 | 867 | vitoclose 868 | 869 | 870 | 871 | F2D4CBD3-8C5E-42EE-903C-DDD8ADA6F33B 872 | 873 | 874 | destinationuid 875 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 876 | modifiers 877 | 0 878 | modifiersubtext 879 | 880 | vitoclose 881 | 882 | 883 | 884 | F6F03505-7E5B-44D3-9A34-845ABDC79BA1 885 | 886 | 887 | destinationuid 888 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 889 | modifiers 890 | 0 891 | modifiersubtext 892 | 893 | vitoclose 894 | 895 | 896 | 897 | FA40A7DB-25B4-464C-B269-EC046612AD60 898 | 899 | 900 | destinationuid 901 | D0E510A1-8928-4339-A865-18534BEB6E01 902 | modifiers 903 | 0 904 | modifiersubtext 905 | 906 | vitoclose 907 | 908 | 909 | 910 | 911 | createdby 912 | Paul Ryley 913 | description 914 | Alfred workflow for The Archive 915 | disabled 916 | 917 | name 918 | The Archive 919 | objects 920 | 921 | 922 | config 923 | 924 | browser 925 | 926 | spaces 927 | 928 | url 929 | https://ko-fi.com/pryley 930 | utf8 931 | 932 | 933 | type 934 | alfred.workflow.action.openurl 935 | uid 936 | BC34D5F9-85CA-4E33-A951-941FE061EEE8 937 | version 938 | 1 939 | 940 | 941 | config 942 | 943 | argumenttype 944 | 2 945 | keyword 946 | ardonate 947 | subtext 948 | If you find this workflow useful, please consider a donation 949 | text 950 | Make a donation 951 | withspace 952 | 953 | 954 | type 955 | alfred.workflow.input.keyword 956 | uid 957 | 8C6B9363-12F2-4E71-8CE7-D1D9777F05C3 958 | version 959 | 1 960 | 961 | 962 | config 963 | 964 | argumenttype 965 | 2 966 | keyword 967 | arhelp 968 | subtext 969 | 970 | text 971 | Read the doumentation 972 | withspace 973 | 974 | 975 | type 976 | alfred.workflow.input.keyword 977 | uid 978 | 0F5540E1-5999-4328-9C24-3C9E18E2746D 979 | version 980 | 1 981 | 982 | 983 | config 984 | 985 | browser 986 | 987 | spaces 988 | 989 | url 990 | https://github.com/pryley/alfred-the-archive/blob/master/README.md 991 | utf8 992 | 993 | 994 | type 995 | alfred.workflow.action.openurl 996 | uid 997 | E1BE1374-4C3C-483D-B093-3AFB164AA55A 998 | version 999 | 1 1000 | 1001 | 1002 | config 1003 | 1004 | lastpathcomponent 1005 | 1006 | onlyshowifquerypopulated 1007 | 1008 | removeextension 1009 | 1010 | text 1011 | The Note will be opened after the import... 1012 | title 1013 | Fetching URL 1014 | 1015 | type 1016 | alfred.workflow.output.notification 1017 | uid 1018 | C9B46D25-C13C-4CBC-A087-787CB09B06E5 1019 | version 1020 | 1 1021 | 1022 | 1023 | config 1024 | 1025 | concurrently 1026 | 1027 | escaping 1028 | 0 1029 | script 1030 | 1031 | scriptargtype 1032 | 1 1033 | scriptfile 1034 | fetch_url.py 1035 | type 1036 | 8 1037 | 1038 | type 1039 | alfred.workflow.action.script 1040 | uid 1041 | 9C2A4DF6-ECF8-45B0-9980-FBE6B1DE2739 1042 | version 1043 | 2 1044 | 1045 | 1046 | config 1047 | 1048 | argumenttype 1049 | 0 1050 | keyword 1051 | arurl 1052 | subtext 1053 | Provide a valid URL beginning with http(s) 1054 | text 1055 | Create note from an URL 1056 | withspace 1057 | 1058 | 1059 | type 1060 | alfred.workflow.input.keyword 1061 | uid 1062 | DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D 1063 | version 1064 | 1 1065 | 1066 | 1067 | config 1068 | 1069 | action 1070 | 0 1071 | argument 1072 | 0 1073 | focusedappvariable 1074 | 1075 | focusedappvariablename 1076 | 1077 | hotkey 1078 | 0 1079 | hotmod 1080 | 0 1081 | hotstring 1082 | 1083 | leftcursor 1084 | 1085 | modsmode 1086 | 0 1087 | relatedAppsMode 1088 | 0 1089 | 1090 | type 1091 | alfred.workflow.trigger.hotkey 1092 | uid 1093 | 724B20C2-2A71-4470-AA68-E9B53C3E089D 1094 | version 1095 | 2 1096 | 1097 | 1098 | config 1099 | 1100 | seconds 1101 | .5 1102 | 1103 | type 1104 | alfred.workflow.utility.delay 1105 | uid 1106 | 0BC841DD-23D7-4621-BB77-3C6851C20031 1107 | version 1108 | 1 1109 | 1110 | 1111 | config 1112 | 1113 | conditions 1114 | 1115 | 1116 | inputstring 1117 | 1118 | matchcasesensitive 1119 | 1120 | matchmode 1121 | 4 1122 | matchstring 1123 | ^http[s]?://.+ 1124 | outputlabel 1125 | URL 1126 | uid 1127 | 8D1F8B77-D912-457F-AB03-DA333DAA4E8B 1128 | 1129 | 1130 | elselabel 1131 | else 1132 | 1133 | type 1134 | alfred.workflow.utility.conditional 1135 | uid 1136 | 5679BD15-58A7-4FCF-9737-E6B573CE4779 1137 | version 1138 | 1 1139 | 1140 | 1141 | config 1142 | 1143 | argumenttype 1144 | 2 1145 | keyword 1146 | arrandom 1147 | subtext 1148 | Open a random note in The Archive 1149 | text 1150 | Random note 1151 | withspace 1152 | 1153 | 1154 | type 1155 | alfred.workflow.input.keyword 1156 | uid 1157 | A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4 1158 | version 1159 | 1 1160 | 1161 | 1162 | config 1163 | 1164 | action 1165 | 0 1166 | argument 1167 | 0 1168 | focusedappvariable 1169 | 1170 | focusedappvariablename 1171 | 1172 | hotkey 1173 | 0 1174 | hotmod 1175 | 0 1176 | hotstring 1177 | 1178 | leftcursor 1179 | 1180 | modsmode 1181 | 0 1182 | relatedAppsMode 1183 | 0 1184 | 1185 | type 1186 | alfred.workflow.trigger.hotkey 1187 | uid 1188 | ABB1A2DA-ECDB-4ECF-AAAE-EACF4246706D 1189 | version 1190 | 2 1191 | 1192 | 1193 | config 1194 | 1195 | lastpathcomponent 1196 | 1197 | onlyshowifquerypopulated 1198 | 1199 | removeextension 1200 | 1201 | text 1202 | Cannot fetch the URL 1203 | title 1204 | Error 1205 | 1206 | type 1207 | alfred.workflow.output.notification 1208 | uid 1209 | B6D96F39-3BF6-4663-BF58-33CD36A2433D 1210 | version 1211 | 1 1212 | 1213 | 1214 | config 1215 | 1216 | concurrently 1217 | 1218 | escaping 1219 | 0 1220 | script 1221 | 1222 | scriptargtype 1223 | 1 1224 | scriptfile 1225 | random_note.py 1226 | type 1227 | 8 1228 | 1229 | type 1230 | alfred.workflow.action.script 1231 | uid 1232 | 6B5486CD-8FE6-493A-AB5E-DC1E63F6979F 1233 | version 1234 | 2 1235 | 1236 | 1237 | config 1238 | 1239 | conditions 1240 | 1241 | 1242 | inputstring 1243 | 1244 | matchcasesensitive 1245 | 1246 | matchmode 1247 | 0 1248 | matchstring 1249 | 1250 | outputlabel 1251 | If fetch unsuccessful 1252 | uid 1253 | CFCFC687-F6EB-434F-B483-6B71BE71AF5B 1254 | 1255 | 1256 | elselabel 1257 | else 1258 | 1259 | type 1260 | alfred.workflow.utility.conditional 1261 | uid 1262 | 97B0EE32-A8A1-405E-B0F2-C459AC7FC3E3 1263 | version 1264 | 1 1265 | 1266 | 1267 | config 1268 | 1269 | triggerid 1270 | ar:config 1271 | 1272 | type 1273 | alfred.workflow.trigger.external 1274 | uid 1275 | E0CED2B6-51DD-4178-B6BF-5FC59F6EE725 1276 | version 1277 | 1 1278 | 1279 | 1280 | config 1281 | 1282 | alfredfiltersresults 1283 | 1284 | alfredfiltersresultsmatchmode 1285 | 0 1286 | argumenttreatemptyqueryasnil 1287 | 1288 | argumenttrimmode 1289 | 0 1290 | argumenttype 1291 | 1 1292 | escaping 1293 | 0 1294 | keyword 1295 | arconfig 1296 | queuedelaycustom 1297 | 3 1298 | queuedelayimmediatelyinitially 1299 | 1300 | queuedelaymode 1301 | 0 1302 | queuemode 1303 | 1 1304 | runningsubtext 1305 | 1306 | script 1307 | 1308 | scriptargtype 1309 | 1 1310 | scriptfile 1311 | config.py 1312 | subtext 1313 | 1314 | title 1315 | Configure the workflow options 1316 | type 1317 | 8 1318 | withspace 1319 | 1320 | 1321 | type 1322 | alfred.workflow.input.scriptfilter 1323 | uid 1324 | ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B 1325 | version 1326 | 3 1327 | 1328 | 1329 | config 1330 | 1331 | action 1332 | 0 1333 | argument 1334 | 0 1335 | focusedappvariable 1336 | 1337 | focusedappvariablename 1338 | 1339 | hotkey 1340 | 0 1341 | hotmod 1342 | 0 1343 | hotstring 1344 | 1345 | leftcursor 1346 | 1347 | modsmode 1348 | 0 1349 | relatedAppsMode 1350 | 0 1351 | 1352 | type 1353 | alfred.workflow.trigger.hotkey 1354 | uid 1355 | 0F836984-A230-4C9E-A376-2A6F54239A8D 1356 | version 1357 | 2 1358 | 1359 | 1360 | config 1361 | 1362 | concurrently 1363 | 1364 | escaping 1365 | 0 1366 | script 1367 | 1368 | scriptargtype 1369 | 1 1370 | scriptfile 1371 | create_note.py 1372 | type 1373 | 8 1374 | 1375 | type 1376 | alfred.workflow.action.script 1377 | uid 1378 | D276EC74-1F27-4BA5-97A8-A4E9D1020D2A 1379 | version 1380 | 2 1381 | 1382 | 1383 | config 1384 | 1385 | externaltriggerid 1386 | ar:config 1387 | passinputasargument 1388 | 1389 | passvariables 1390 | 1391 | workflowbundleid 1392 | self 1393 | 1394 | type 1395 | alfred.workflow.output.callexternaltrigger 1396 | uid 1397 | A8B79535-E3CC-4A12-B1A0-CBE9634E5804 1398 | version 1399 | 1 1400 | 1401 | 1402 | config 1403 | 1404 | seconds 1405 | 1 1406 | 1407 | type 1408 | alfred.workflow.utility.delay 1409 | uid 1410 | EF0769B1-0BDA-4D96-B640-1FA8EB1FD7BB 1411 | version 1412 | 1 1413 | 1414 | 1415 | config 1416 | 1417 | argument 1418 | 1419 | passthroughargument 1420 | 1421 | variables 1422 | 1423 | action_key_value 1424 | {query} 1425 | 1426 | 1427 | type 1428 | alfred.workflow.utility.argument 1429 | uid 1430 | 699C78CF-86C9-47FA-A077-DB7462FDE43F 1431 | version 1432 | 1 1433 | 1434 | 1435 | config 1436 | 1437 | action 1438 | 0 1439 | argument 1440 | 0 1441 | focusedappvariable 1442 | 1443 | focusedappvariablename 1444 | 1445 | hotkey 1446 | 0 1447 | hotmod 1448 | 0 1449 | hotstring 1450 | 1451 | leftcursor 1452 | 1453 | modsmode 1454 | 0 1455 | relatedAppsMode 1456 | 0 1457 | 1458 | type 1459 | alfred.workflow.trigger.hotkey 1460 | uid 1461 | F2AF7DA9-9371-485E-B037-DF138D6379C1 1462 | version 1463 | 2 1464 | 1465 | 1466 | config 1467 | 1468 | alfredfiltersresults 1469 | 1470 | alfredfiltersresultsmatchmode 1471 | 0 1472 | argumenttreatemptyqueryasnil 1473 | 1474 | argumenttrimmode 1475 | 0 1476 | argumenttype 1477 | 0 1478 | escaping 1479 | 0 1480 | keyword 1481 | arnew 1482 | queuedelaycustom 1483 | 3 1484 | queuedelayimmediatelyinitially 1485 | 1486 | queuedelaymode 1487 | 0 1488 | queuemode 1489 | 1 1490 | runningsubtext 1491 | 1492 | script 1493 | 1494 | scriptargtype 1495 | 1 1496 | scriptfile 1497 | search_templates.py 1498 | subtext 1499 | Enter the title and optionally some tags 1500 | title 1501 | Create note 1502 | type 1503 | 8 1504 | withspace 1505 | 1506 | 1507 | type 1508 | alfred.workflow.input.scriptfilter 1509 | uid 1510 | A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9 1511 | version 1512 | 3 1513 | 1514 | 1515 | config 1516 | 1517 | externaltriggerid 1518 | ar:todo 1519 | passinputasargument 1520 | 1521 | passvariables 1522 | 1523 | workflowbundleid 1524 | self 1525 | 1526 | type 1527 | alfred.workflow.output.callexternaltrigger 1528 | uid 1529 | FD181211-B1A6-463B-AF31-28A941B28F2E 1530 | version 1531 | 1 1532 | 1533 | 1534 | config 1535 | 1536 | concurrently 1537 | 1538 | escaping 1539 | 0 1540 | script 1541 | 1542 | scriptargtype 1543 | 1 1544 | scriptfile 1545 | toggle_task.py 1546 | type 1547 | 8 1548 | 1549 | type 1550 | alfred.workflow.action.script 1551 | uid 1552 | 22568BCE-A99B-499A-B22B-D125B36C3A97 1553 | version 1554 | 2 1555 | 1556 | 1557 | config 1558 | 1559 | triggerid 1560 | ar:create 1561 | 1562 | type 1563 | alfred.workflow.trigger.external 1564 | uid 1565 | 3078B7FC-DAD0-48C1-938B-E2C5102800D8 1566 | version 1567 | 1 1568 | 1569 | 1570 | config 1571 | 1572 | argument 1573 | {var:split1} 1574 | passthroughargument 1575 | 1576 | variables 1577 | 1578 | clipboard 1579 | {clipboard} 1580 | paste 1581 | {var:split3} 1582 | template 1583 | {var:split2} 1584 | 1585 | 1586 | type 1587 | alfred.workflow.utility.argument 1588 | uid 1589 | D4A81EE0-15F4-4F07-B5B6-FD9E7646EB3A 1590 | version 1591 | 1 1592 | 1593 | 1594 | config 1595 | 1596 | delimiter 1597 | |> 1598 | trimarguments 1599 | 1600 | variableprefix 1601 | split 1602 | 1603 | type 1604 | alfred.workflow.utility.split 1605 | uid 1606 | CCFB27EC-FE2A-4853-92F9-66D2E16EC154 1607 | version 1608 | 1 1609 | 1610 | 1611 | config 1612 | 1613 | triggerid 1614 | ar:todo 1615 | 1616 | type 1617 | alfred.workflow.trigger.external 1618 | uid 1619 | 966EB023-178A-428E-B2CB-576954E4A33A 1620 | version 1621 | 1 1622 | 1623 | 1624 | config 1625 | 1626 | action 1627 | 0 1628 | argument 1629 | 0 1630 | focusedappvariable 1631 | 1632 | focusedappvariablename 1633 | 1634 | hotkey 1635 | 0 1636 | hotmod 1637 | 0 1638 | hotstring 1639 | 1640 | leftcursor 1641 | 1642 | modsmode 1643 | 0 1644 | relatedAppsMode 1645 | 0 1646 | 1647 | type 1648 | alfred.workflow.trigger.hotkey 1649 | uid 1650 | B58A48B9-E9D2-46BA-B2FC-8D52D0002AFD 1651 | version 1652 | 2 1653 | 1654 | 1655 | config 1656 | 1657 | alfredfiltersresults 1658 | 1659 | alfredfiltersresultsmatchmode 1660 | 0 1661 | argumenttreatemptyqueryasnil 1662 | 1663 | argumenttrimmode 1664 | 0 1665 | argumenttype 1666 | 1 1667 | escaping 1668 | 0 1669 | keyword 1670 | artask 1671 | queuedelaycustom 1672 | 3 1673 | queuedelayimmediatelyinitially 1674 | 1675 | queuedelaymode 1676 | 0 1677 | queuemode 1678 | 1 1679 | runningsubtext 1680 | Searching... 1681 | script 1682 | 1683 | scriptargtype 1684 | 1 1685 | scriptfile 1686 | search_tasks.py 1687 | subtext 1688 | Search for tasks in your notes 1689 | title 1690 | Search tasks 1691 | type 1692 | 8 1693 | withspace 1694 | 1695 | 1696 | type 1697 | alfred.workflow.input.scriptfilter 1698 | uid 1699 | 524CFE69-2161-4618-BC65-7D380B0B3EAD 1700 | version 1701 | 3 1702 | 1703 | 1704 | config 1705 | 1706 | concurrently 1707 | 1708 | escaping 1709 | 0 1710 | script 1711 | 1712 | scriptargtype 1713 | 1 1714 | scriptfile 1715 | get_title.py 1716 | type 1717 | 8 1718 | 1719 | type 1720 | alfred.workflow.action.script 1721 | uid 1722 | D6A73E77-7D81-45B7-AC0B-B6E59D5B94DD 1723 | version 1724 | 2 1725 | 1726 | 1727 | config 1728 | 1729 | openwith 1730 | 1731 | sourcefile 1732 | 1733 | 1734 | type 1735 | alfred.workflow.action.openfile 1736 | uid 1737 | 8A5F7A4E-FC3A-466E-A53A-38313E9F8022 1738 | version 1739 | 3 1740 | 1741 | 1742 | config 1743 | 1744 | alfredfiltersresults 1745 | 1746 | alfredfiltersresultsmatchmode 1747 | 0 1748 | argumenttreatemptyqueryasnil 1749 | 1750 | argumenttrimmode 1751 | 0 1752 | argumenttype 1753 | 1 1754 | escaping 1755 | 0 1756 | keyword 1757 | artag 1758 | queuedelaycustom 1759 | 3 1760 | queuedelayimmediatelyinitially 1761 | 1762 | queuedelaymode 1763 | 0 1764 | queuemode 1765 | 1 1766 | runningsubtext 1767 | Searching... 1768 | script 1769 | 1770 | scriptargtype 1771 | 1 1772 | scriptfile 1773 | search_tags.py 1774 | subtext 1775 | Search the tags in your notes 1776 | title 1777 | Search tags 1778 | type 1779 | 8 1780 | withspace 1781 | 1782 | 1783 | type 1784 | alfred.workflow.input.scriptfilter 1785 | uid 1786 | CB491715-463C-4A1F-BF00-4EF95002AF65 1787 | version 1788 | 3 1789 | 1790 | 1791 | config 1792 | 1793 | action 1794 | 0 1795 | argument 1796 | 0 1797 | focusedappvariable 1798 | 1799 | focusedappvariablename 1800 | 1801 | hotkey 1802 | 0 1803 | hotmod 1804 | 0 1805 | hotstring 1806 | 1807 | leftcursor 1808 | 1809 | modsmode 1810 | 0 1811 | relatedAppsMode 1812 | 0 1813 | 1814 | type 1815 | alfred.workflow.trigger.hotkey 1816 | uid 1817 | BE57B8E8-5E6A-43EC-8087-342FE3342B6C 1818 | version 1819 | 2 1820 | 1821 | 1822 | config 1823 | 1824 | browser 1825 | 1826 | spaces 1827 | 1828 | url 1829 | thearchive://match/{query} 1830 | utf8 1831 | 1832 | 1833 | type 1834 | alfred.workflow.action.openurl 1835 | uid 1836 | C60A62FF-9B59-4C3C-99F3-807373F2125E 1837 | version 1838 | 1 1839 | 1840 | 1841 | config 1842 | 1843 | externaltriggerid 1844 | ar:create 1845 | passinputasargument 1846 | 1847 | passvariables 1848 | 1849 | workflowbundleid 1850 | self 1851 | 1852 | type 1853 | alfred.workflow.output.callexternaltrigger 1854 | uid 1855 | CE0C3E3D-3480-4860-8AEF-D91987553D48 1856 | version 1857 | 1 1858 | 1859 | 1860 | config 1861 | 1862 | conditions 1863 | 1864 | 1865 | inputstring 1866 | 1867 | matchcasesensitive 1868 | 1869 | matchmode 1870 | 4 1871 | matchstring 1872 | ^\/ 1873 | outputlabel 1874 | If file exists 1875 | uid 1876 | B649ABA2-9104-4A0B-90FA-B1207CE605E5 1877 | 1878 | 1879 | elselabel 1880 | else 1881 | 1882 | type 1883 | alfred.workflow.utility.conditional 1884 | uid 1885 | B78F0AC4-5704-4E41-A5C5-41D7EF829577 1886 | version 1887 | 1 1888 | 1889 | 1890 | config 1891 | 1892 | acceptsmulti 1893 | 0 1894 | filetypes 1895 | 1896 | public.jpeg 1897 | public.png 1898 | 1899 | name 1900 | Add image to The Archive 1901 | 1902 | type 1903 | alfred.workflow.trigger.action 1904 | uid 1905 | D7113CA2-175F-4D98-B738-A732E4826D02 1906 | version 1907 | 1 1908 | 1909 | 1910 | config 1911 | 1912 | concurrently 1913 | 1914 | escaping 1915 | 0 1916 | script 1917 | python import_image.py "{query}" 1918 | scriptargtype 1919 | 0 1920 | scriptfile 1921 | insert_image.py 1922 | type 1923 | 0 1924 | 1925 | type 1926 | alfred.workflow.action.script 1927 | uid 1928 | 42848B7A-9D43-4C79-9E97-A8990FACBAE7 1929 | version 1930 | 2 1931 | 1932 | 1933 | config 1934 | 1935 | autopaste 1936 | 1937 | clipboardtext 1938 | {query} 1939 | ignoredynamicplaceholders 1940 | 1941 | transient 1942 | 1943 | 1944 | type 1945 | alfred.workflow.output.clipboard 1946 | uid 1947 | D7F05A73-355B-4C77-A4F8-F301CF68FB9A 1948 | version 1949 | 3 1950 | 1951 | 1952 | config 1953 | 1954 | concurrently 1955 | 1956 | escaping 1957 | 0 1958 | script 1959 | 1960 | scriptargtype 1961 | 1 1962 | scriptfile 1963 | get_zettel_link.py 1964 | type 1965 | 8 1966 | 1967 | type 1968 | alfred.workflow.action.script 1969 | uid 1970 | 06634071-A34F-47EA-9A93-224F1E437E99 1971 | version 1972 | 2 1973 | 1974 | 1975 | config 1976 | 1977 | alfredfiltersresults 1978 | 1979 | alfredfiltersresultsmatchmode 1980 | 0 1981 | argumenttreatemptyqueryasnil 1982 | 1983 | argumenttrimmode 1984 | 0 1985 | argumenttype 1986 | 1 1987 | escaping 1988 | 0 1989 | keyword 1990 | ar 1991 | queuedelaycustom 1992 | 3 1993 | queuedelayimmediatelyinitially 1994 | 1995 | queuedelaymode 1996 | 0 1997 | queuemode 1998 | 1 1999 | runningsubtext 2000 | Searching... 2001 | script 2002 | 2003 | scriptargtype 2004 | 1 2005 | scriptfile 2006 | search_notes.py 2007 | subtext 2008 | Search for {query} 2009 | title 2010 | Search The Archive 2011 | type 2012 | 8 2013 | withspace 2014 | 2015 | 2016 | type 2017 | alfred.workflow.input.scriptfilter 2018 | uid 2019 | 629E7681-4B3B-44F8-931C-617775EE6CFA 2020 | version 2021 | 3 2022 | 2023 | 2024 | config 2025 | 2026 | action 2027 | 0 2028 | argument 2029 | 0 2030 | focusedappvariable 2031 | 2032 | focusedappvariablename 2033 | 2034 | hotkey 2035 | 0 2036 | hotmod 2037 | 0 2038 | hotstring 2039 | 2040 | leftcursor 2041 | 2042 | modsmode 2043 | 0 2044 | relatedAppsMode 2045 | 0 2046 | 2047 | type 2048 | alfred.workflow.trigger.hotkey 2049 | uid 2050 | E83305CB-1BAA-457E-93A8-0B9C7689D3C7 2051 | version 2052 | 2 2053 | 2054 | 2055 | config 2056 | 2057 | triggerid 2058 | ar:search 2059 | 2060 | type 2061 | alfred.workflow.trigger.external 2062 | uid 2063 | 47A8B5B3-11A9-4177-A3DA-18CDE6C4F71D 2064 | version 2065 | 1 2066 | 2067 | 2068 | config 2069 | 2070 | autopaste 2071 | 2072 | clipboardtext 2073 | {query} 2074 | ignoredynamicplaceholders 2075 | 2076 | transient 2077 | 2078 | 2079 | type 2080 | alfred.workflow.output.clipboard 2081 | uid 2082 | FA40A7DB-25B4-464C-B269-EC046612AD60 2083 | version 2084 | 3 2085 | 2086 | 2087 | config 2088 | 2089 | concurrently 2090 | 2091 | escaping 2092 | 0 2093 | script 2094 | 2095 | scriptargtype 2096 | 1 2097 | scriptfile 2098 | get_md_link.py 2099 | type 2100 | 8 2101 | 2102 | type 2103 | alfred.workflow.action.script 2104 | uid 2105 | A73C0944-0E7B-483F-BC14-1A0089887B05 2106 | version 2107 | 2 2108 | 2109 | 2110 | config 2111 | 2112 | lastpathcomponent 2113 | 2114 | onlyshowifquerypopulated 2115 | 2116 | removeextension 2117 | 2118 | text 2119 | {query} 2120 | title 2121 | Link copied to clipboard 2122 | 2123 | type 2124 | alfred.workflow.output.notification 2125 | uid 2126 | D0E510A1-8928-4339-A865-18534BEB6E01 2127 | version 2128 | 1 2129 | 2130 | 2131 | config 2132 | 2133 | argument 2134 | {var:action2} 2135 | passthroughargument 2136 | 2137 | variables 2138 | 2139 | 2140 | type 2141 | alfred.workflow.utility.argument 2142 | uid 2143 | D2AD3BCE-73FA-4344-B003-A57E66E4AC6B 2144 | version 2145 | 1 2146 | 2147 | 2148 | config 2149 | 2150 | conditions 2151 | 2152 | 2153 | inputstring 2154 | {var:action1} 2155 | matchcasesensitive 2156 | 2157 | matchmode 2158 | 0 2159 | matchstring 2160 | editor 2161 | outputlabel 2162 | editor 2163 | uid 2164 | 6D724BD9-BEF7-4D28-8DCC-A594E968CD3E 2165 | 2166 | 2167 | inputstring 2168 | {var:action1} 2169 | matchcasesensitive 2170 | 2171 | matchmode 2172 | 0 2173 | matchstring 2174 | wiki_link 2175 | outputlabel 2176 | wiki_link 2177 | uid 2178 | 1ADF607C-65D9-4B0E-B580-428737D4FE3F 2179 | 2180 | 2181 | inputstring 2182 | {var:action1} 2183 | matchcasesensitive 2184 | 2185 | matchmode 2186 | 0 2187 | matchstring 2188 | markdown_link 2189 | outputlabel 2190 | markdown_link 2191 | uid 2192 | 03A97A98-84AF-47FA-BD7A-F5BD9090159F 2193 | 2194 | 2195 | inputstring 2196 | {var:action1} 2197 | matchcasesensitive 2198 | 2199 | matchmode 2200 | 0 2201 | matchstring 2202 | delete 2203 | outputlabel 2204 | delete 2205 | uid 2206 | 3961D0C5-8015-4EDE-8753-F201EB4B11C1 2207 | 2208 | 2209 | inputstring 2210 | {var:action1} 2211 | matchcasesensitive 2212 | 2213 | matchmode 2214 | 0 2215 | matchstring 2216 | back 2217 | outputlabel 2218 | back 2219 | uid 2220 | 325682B6-E189-423E-A2E9-2D12608FDA53 2221 | 2222 | 2223 | elselabel 2224 | else 2225 | 2226 | type 2227 | alfred.workflow.utility.conditional 2228 | uid 2229 | 1AD1E2CF-FCB9-45E5-B8F2-9C6B0CEAABD6 2230 | version 2231 | 1 2232 | 2233 | 2234 | config 2235 | 2236 | alfredfiltersresults 2237 | 2238 | alfredfiltersresultsmatchmode 2239 | 0 2240 | argumenttreatemptyqueryasnil 2241 | 2242 | argumenttrimmode 2243 | 0 2244 | argumenttype 2245 | 1 2246 | escaping 2247 | 0 2248 | queuedelaycustom 2249 | 3 2250 | queuedelayimmediatelyinitially 2251 | 2252 | queuedelaymode 2253 | 0 2254 | queuemode 2255 | 1 2256 | runningsubtext 2257 | 2258 | script 2259 | 2260 | scriptargtype 2261 | 1 2262 | scriptfile 2263 | search_actions.py 2264 | subtext 2265 | 2266 | title 2267 | 2268 | type 2269 | 8 2270 | withspace 2271 | 2272 | 2273 | type 2274 | alfred.workflow.input.scriptfilter 2275 | uid 2276 | 657FD06E-6635-4C54-88C2-8FF658370FD7 2277 | version 2278 | 3 2279 | 2280 | 2281 | config 2282 | 2283 | action 2284 | 0 2285 | argument 2286 | 3 2287 | argumenttext 2288 | # 2289 | focusedappvariable 2290 | 2291 | focusedappvariablename 2292 | 2293 | hotkey 2294 | 18 2295 | hotmod 2296 | 1048576 2297 | hotstring 2298 | 1 2299 | leftcursor 2300 | 2301 | modsmode 2302 | 0 2303 | relatedApps 2304 | 2305 | de.zettelkasten.TheArchive 2306 | 2307 | relatedAppsMode 2308 | 1 2309 | 2310 | type 2311 | alfred.workflow.trigger.hotkey 2312 | uid 2313 | 28072C72-6F5F-49D3-9C79-F39D03C75A11 2314 | version 2315 | 2 2316 | 2317 | 2318 | config 2319 | 2320 | applescript 2321 | on alfred_script(q) 2322 | set posixfile to POSIX file q 2323 | tell application "Finder" 2324 | move posixfile to trash 2325 | end tell 2326 | return q 2327 | end alfred_script 2328 | cachescript 2329 | 2330 | 2331 | type 2332 | alfred.workflow.action.applescript 2333 | uid 2334 | C813B26C-8583-4087-9E6E-1FAC323A7F0F 2335 | version 2336 | 1 2337 | 2338 | 2339 | config 2340 | 2341 | lastpathcomponent 2342 | 2343 | onlyshowifquerypopulated 2344 | 2345 | removeextension 2346 | 2347 | text 2348 | {query} 2349 | title 2350 | File deleted 2351 | 2352 | type 2353 | alfred.workflow.output.notification 2354 | uid 2355 | 59FC67F4-40A5-440E-B854-0B65823BD164 2356 | version 2357 | 1 2358 | 2359 | 2360 | config 2361 | 2362 | argument 2363 | {var:action2} 2364 | passthroughargument 2365 | 2366 | variables 2367 | 2368 | 2369 | type 2370 | alfred.workflow.utility.argument 2371 | uid 2372 | A4A95B3D-BE6A-45BC-A53B-74984F4F48A7 2373 | version 2374 | 1 2375 | 2376 | 2377 | config 2378 | 2379 | delimiter 2380 | |> 2381 | trimarguments 2382 | 2383 | variableprefix 2384 | action 2385 | 2386 | type 2387 | alfred.workflow.utility.split 2388 | uid 2389 | DBE958B2-368A-48F9-A8AB-1DC9FC300B27 2390 | version 2391 | 1 2392 | 2393 | 2394 | config 2395 | 2396 | argument 2397 | 2398 | passthroughargument 2399 | 2400 | variables 2401 | 2402 | 2403 | type 2404 | alfred.workflow.utility.argument 2405 | uid 2406 | C767AF6B-DF2C-40A1-8F23-916EDE028F7F 2407 | version 2408 | 1 2409 | 2410 | 2411 | config 2412 | 2413 | delimiter 2414 | |> 2415 | trimarguments 2416 | 2417 | variableprefix 2418 | path_query 2419 | 2420 | type 2421 | alfred.workflow.utility.split 2422 | uid 2423 | 3666E55C-5EA1-4C6A-9565-22A55CE17403 2424 | version 2425 | 1 2426 | 2427 | 2428 | config 2429 | 2430 | argument 2431 | {var:action2} 2432 | passthroughargument 2433 | 2434 | variables 2435 | 2436 | 2437 | type 2438 | alfred.workflow.utility.argument 2439 | uid 2440 | B45C99C4-5814-48E9-A8C4-426F939F7335 2441 | version 2442 | 1 2443 | 2444 | 2445 | config 2446 | 2447 | argument 2448 | {var:action2} 2449 | passthroughargument 2450 | 2451 | variables 2452 | 2453 | 2454 | type 2455 | alfred.workflow.utility.argument 2456 | uid 2457 | D0A0BB4A-D8DC-4463-A00F-06ABF17CF7F3 2458 | version 2459 | 1 2460 | 2461 | 2462 | config 2463 | 2464 | externaltriggerid 2465 | ar:search 2466 | passinputasargument 2467 | 2468 | passvariables 2469 | 2470 | workflowbundleid 2471 | self 2472 | 2473 | type 2474 | alfred.workflow.output.callexternaltrigger 2475 | uid 2476 | 42489888-94A8-4578-A4CB-BCAE3F2D7339 2477 | version 2478 | 1 2479 | 2480 | 2481 | config 2482 | 2483 | action 2484 | 0 2485 | argument 2486 | 3 2487 | argumenttext 2488 | ## 2489 | focusedappvariable 2490 | 2491 | focusedappvariablename 2492 | 2493 | hotkey 2494 | 19 2495 | hotmod 2496 | 1048576 2497 | hotstring 2498 | 2 2499 | leftcursor 2500 | 2501 | modsmode 2502 | 0 2503 | relatedApps 2504 | 2505 | de.zettelkasten.TheArchive 2506 | 2507 | relatedAppsMode 2508 | 1 2509 | 2510 | type 2511 | alfred.workflow.trigger.hotkey 2512 | uid 2513 | 65FB1EF4-D09E-4070-BB2E-E3FF6FB331EA 2514 | version 2515 | 2 2516 | 2517 | 2518 | config 2519 | 2520 | applescript 2521 | use AppleScript version "2.4" 2522 | use framework "AppKit" 2523 | use framework "Foundation" 2524 | use scripting additions 2525 | 2526 | on alfred_script(q) 2527 | set oldClip to my fetchStorableClipboard() 2528 | set thePasteboard to current application's NSPasteboard's generalPasteboard() 2529 | set theCount to thePasteboard's changeCount() 2530 | tell application "System Events" to keystroke "c" using {command down} 2531 | repeat 20 times 2532 | if thePasteboard's changeCount() is not theCount then exit repeat 2533 | delay 0.1 2534 | end repeat 2535 | set input to (the clipboard) 2536 | if ((q as string) is equal to "```") then 2537 | set trimmedText to trimText(trimParagraphs(input, q), return) 2538 | set newText to q & return & trimmedText & return & q & return 2539 | else 2540 | set regex to "^([#]+)?(\\s+)?(.*)" 2541 | set heading to regex_match from the input against regex given replacement:" $3" 2542 | set newText to q & trimText(heading, return) & return 2543 | end if 2544 | set the clipboard to newText 2545 | tell application "System Events" to keystroke "v" using {command down} 2546 | delay 0.2 2547 | my putOnClipboard:oldClip 2548 | end alfred_script 2549 | 2550 | on fetchStorableClipboard() 2551 | set aMutableArray to current application's NSMutableArray's array() 2552 | set thePasteboard to current application's NSPasteboard's generalPasteboard() 2553 | repeat with anItem in thePasteboard's pasteboardItems() 2554 | set newPBItem to current application's NSPasteboardItem's alloc()'s init() 2555 | set theTypes to anItem's |types|() 2556 | repeat with aType in theTypes 2557 | set theData to (anItem's dataForType:aType)'s mutableCopy() 2558 | if theData is not missing value then 2559 | (newPBItem's setData:theData forType:aType) 2560 | end if 2561 | end repeat 2562 | (aMutableArray's addObject:newPBItem) 2563 | end repeat 2564 | return aMutableArray 2565 | end fetchStorableClipboard 2566 | 2567 | on putOnClipboard:theArray 2568 | set thePasteboard to current application's NSPasteboard's generalPasteboard() 2569 | thePasteboard's clearContents() 2570 | thePasteboard's writeObjects:theArray 2571 | end putOnClipboard: 2572 | 2573 | on regex_match against pattern from str given replacement:fmt 2574 | set regex to current application's NSRegularExpression's regularExpressionWithPattern:pattern options:(current application's NSRegularExpressionCaseInsensitive) |error|:(missing value) 2575 | (regex's stringByReplacingMatchesInString:str options:0 range:{0, length of str} withTemplate:fmt) as text 2576 | end regex_match 2577 | 2578 | on trimParagraphs(theText, theCharactersToTrim) 2579 | set theParagraphs to every paragraph of theText 2580 | repeat with a from 1 to count of paragraphs of theText 2581 | set theCurrentParagraph to item a of theParagraphs 2582 | set item a of theParagraphs to trimText(theCurrentParagraph, theCharactersToTrim) 2583 | end repeat 2584 | set AppleScript's text item delimiters to return 2585 | set theText to theParagraphs as string 2586 | set AppleScript's text item delimiters to "" 2587 | return theText 2588 | end trimParagraphs 2589 | 2590 | on trimText(theText, theCharactersToTrim) 2591 | set theTrimLength to length of theCharactersToTrim 2592 | repeat while theText begins with theCharactersToTrim 2593 | try 2594 | set theText to characters (theTrimLength + 1) thru -1 of theText as string 2595 | on error 2596 | return "" 2597 | end try 2598 | end repeat 2599 | repeat while theText ends with theCharactersToTrim 2600 | try 2601 | set theText to characters 1 thru -(theTrimLength + 1) of theText as string 2602 | on error 2603 | return "" 2604 | end try 2605 | end repeat 2606 | return theText 2607 | end trimText 2608 | cachescript 2609 | 2610 | 2611 | type 2612 | alfred.workflow.action.applescript 2613 | uid 2614 | 51A1F4B9-D0F3-40BD-AB30-22AF874BA1A9 2615 | version 2616 | 1 2617 | 2618 | 2619 | config 2620 | 2621 | count 2622 | 1 2623 | keychar 2624 | l 2625 | keycode 2626 | -1 2627 | keymod 2628 | 1179648 2629 | overridewithargument 2630 | 2631 | 2632 | type 2633 | alfred.workflow.output.dispatchkeycombo 2634 | uid 2635 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 2636 | version 2637 | 1 2638 | 2639 | 2640 | config 2641 | 2642 | argument 2643 | {var:action2} 2644 | passthroughargument 2645 | 2646 | variables 2647 | 2648 | 2649 | type 2650 | alfred.workflow.utility.argument 2651 | uid 2652 | EB8A1BFE-4152-4203-A6B8-DAA827BA4932 2653 | version 2654 | 1 2655 | 2656 | 2657 | config 2658 | 2659 | action 2660 | 0 2661 | argument 2662 | 3 2663 | argumenttext 2664 | ### 2665 | focusedappvariable 2666 | 2667 | focusedappvariablename 2668 | 2669 | hotkey 2670 | 20 2671 | hotmod 2672 | 1048576 2673 | hotstring 2674 | 3 2675 | leftcursor 2676 | 2677 | modsmode 2678 | 0 2679 | relatedApps 2680 | 2681 | de.zettelkasten.TheArchive 2682 | 2683 | relatedAppsMode 2684 | 1 2685 | 2686 | type 2687 | alfred.workflow.trigger.hotkey 2688 | uid 2689 | F6F03505-7E5B-44D3-9A34-845ABDC79BA1 2690 | version 2691 | 2 2692 | 2693 | 2694 | config 2695 | 2696 | action 2697 | 0 2698 | argument 2699 | 3 2700 | argumenttext 2701 | #### 2702 | focusedappvariable 2703 | 2704 | focusedappvariablename 2705 | 2706 | hotkey 2707 | 21 2708 | hotmod 2709 | 1048576 2710 | hotstring 2711 | 4 2712 | leftcursor 2713 | 2714 | modsmode 2715 | 0 2716 | relatedApps 2717 | 2718 | de.zettelkasten.TheArchive 2719 | 2720 | relatedAppsMode 2721 | 1 2722 | 2723 | type 2724 | alfred.workflow.trigger.hotkey 2725 | uid 2726 | 341A03B4-7E79-4AD7-A347-AF17C634D4FF 2727 | version 2728 | 2 2729 | 2730 | 2731 | config 2732 | 2733 | action 2734 | 0 2735 | argument 2736 | 3 2737 | argumenttext 2738 | ##### 2739 | focusedappvariable 2740 | 2741 | focusedappvariablename 2742 | 2743 | hotkey 2744 | 23 2745 | hotmod 2746 | 1048576 2747 | hotstring 2748 | 5 2749 | leftcursor 2750 | 2751 | modsmode 2752 | 0 2753 | relatedApps 2754 | 2755 | de.zettelkasten.TheArchive 2756 | 2757 | relatedAppsMode 2758 | 1 2759 | 2760 | type 2761 | alfred.workflow.trigger.hotkey 2762 | uid 2763 | F2D4CBD3-8C5E-42EE-903C-DDD8ADA6F33B 2764 | version 2765 | 2 2766 | 2767 | 2768 | config 2769 | 2770 | action 2771 | 0 2772 | argument 2773 | 3 2774 | argumenttext 2775 | ###### 2776 | focusedappvariable 2777 | 2778 | focusedappvariablename 2779 | 2780 | hotkey 2781 | 22 2782 | hotmod 2783 | 1048576 2784 | hotstring 2785 | 6 2786 | leftcursor 2787 | 2788 | modsmode 2789 | 0 2790 | relatedApps 2791 | 2792 | de.zettelkasten.TheArchive 2793 | 2794 | relatedAppsMode 2795 | 1 2796 | 2797 | type 2798 | alfred.workflow.trigger.hotkey 2799 | uid 2800 | 82C3724E-6E6D-4282-A8D5-F528A6D5A0AE 2801 | version 2802 | 2 2803 | 2804 | 2805 | config 2806 | 2807 | action 2808 | 0 2809 | argument 2810 | 3 2811 | argumenttext 2812 | ``` 2813 | focusedappvariable 2814 | 2815 | focusedappvariablename 2816 | 2817 | hotkey 2818 | 50 2819 | hotmod 2820 | 1048576 2821 | hotstring 2822 | ` 2823 | leftcursor 2824 | 2825 | modsmode 2826 | 0 2827 | relatedApps 2828 | 2829 | de.zettelkasten.TheArchive 2830 | 2831 | relatedAppsMode 2832 | 1 2833 | 2834 | type 2835 | alfred.workflow.trigger.hotkey 2836 | uid 2837 | 13D7AF95-E68C-4207-AD54-532455FFBC15 2838 | version 2839 | 2 2840 | 2841 | 2842 | readme 2843 | This is an comprehensive workflow for The Archive that helps you work with your notes more efficiently. 2844 | uidata 2845 | 2846 | 06634071-A34F-47EA-9A93-224F1E437E99 2847 | 2848 | note 2849 | Generate zettel link 2850 | xpos 2851 | 1010 2852 | ypos 2853 | 1360 2854 | 2855 | 0BC841DD-23D7-4621-BB77-3C6851C20031 2856 | 2857 | xpos 2858 | 1150 2859 | ypos 2860 | 340 2861 | 2862 | 0F5540E1-5999-4328-9C24-3C9E18E2746D 2863 | 2864 | note 2865 | Open README.md 2866 | xpos 2867 | 610 2868 | ypos 2869 | 160 2870 | 2871 | 0F836984-A230-4C9E-A376-2A6F54239A8D 2872 | 2873 | colorindex 2874 | 3 2875 | xpos 2876 | 10 2877 | ypos 2878 | 610 2879 | 2880 | 13D7AF95-E68C-4207-AD54-532455FFBC15 2881 | 2882 | colorindex 2883 | 3 2884 | xpos 2885 | 10 2886 | ypos 2887 | 2555 2888 | 2889 | 1AD1E2CF-FCB9-45E5-B8F2-9C6B0CEAABD6 2890 | 2891 | xpos 2892 | 1610 2893 | ypos 2894 | 1660 2895 | 2896 | 22568BCE-A99B-499A-B22B-D125B36C3A97 2897 | 2898 | note 2899 | Toggle the task 2900 | xpos 2901 | 1010 2902 | ypos 2903 | 760 2904 | 2905 | 28072C72-6F5F-49D3-9C79-F39D03C75A11 2906 | 2907 | colorindex 2908 | 3 2909 | xpos 2910 | 10 2911 | ypos 2912 | 1660 2913 | 2914 | 3078B7FC-DAD0-48C1-938B-E2C5102800D8 2915 | 2916 | colorindex 2917 | 7 2918 | xpos 2919 | 210 2920 | ypos 2921 | 760 2922 | 2923 | 341A03B4-7E79-4AD7-A347-AF17C634D4FF 2924 | 2925 | colorindex 2926 | 3 2927 | xpos 2928 | 10 2929 | ypos 2930 | 2110 2931 | 2932 | 3666E55C-5EA1-4C6A-9565-22A55CE17403 2933 | 2934 | xpos 2935 | 1210 2936 | ypos 2937 | 1690 2938 | 2939 | 42489888-94A8-4578-A4CB-BCAE3F2D7339 2940 | 2941 | colorindex 2942 | 7 2943 | xpos 2944 | 2010 2945 | ypos 2946 | 1810 2947 | 2948 | 42848B7A-9D43-4C79-9E97-A8990FACBAE7 2949 | 2950 | note 2951 | Import image 2952 | xpos 2953 | 1010 2954 | ypos 2955 | 1210 2956 | 2957 | 47A8B5B3-11A9-4177-A3DA-18CDE6C4F71D 2958 | 2959 | colorindex 2960 | 7 2961 | xpos 2962 | 210 2963 | ypos 2964 | 1360 2965 | 2966 | 51A1F4B9-D0F3-40BD-AB30-22AF874BA1A9 2967 | 2968 | note 2969 | Change heading level 2970 | xpos 2971 | 1010 2972 | ypos 2973 | 1810 2974 | 2975 | 524CFE69-2161-4618-BC65-7D380B0B3EAD 2976 | 2977 | note 2978 | Search tasks 2979 | xpos 2980 | 610 2981 | ypos 2982 | 910 2983 | 2984 | 5679BD15-58A7-4FCF-9737-E6B573CE4779 2985 | 2986 | xpos 2987 | 810 2988 | ypos 2989 | 345 2990 | 2991 | 59FC67F4-40A5-440E-B854-0B65823BD164 2992 | 2993 | xpos 2994 | 2410 2995 | ypos 2996 | 1660 2997 | 2998 | 629E7681-4B3B-44F8-931C-617775EE6CFA 2999 | 3000 | note 3001 | Search notes 3002 | xpos 3003 | 610 3004 | ypos 3005 | 1360 3006 | 3007 | 657FD06E-6635-4C54-88C2-8FF658370FD7 3008 | 3009 | xpos 3010 | 1360 3011 | ypos 3012 | 1660 3013 | 3014 | 65FB1EF4-D09E-4070-BB2E-E3FF6FB331EA 3015 | 3016 | colorindex 3017 | 3 3018 | xpos 3019 | 10 3020 | ypos 3021 | 1810 3022 | 3023 | 699C78CF-86C9-47FA-A077-DB7462FDE43F 3024 | 3025 | xpos 3026 | 350 3027 | ypos 3028 | 640 3029 | 3030 | 6B5486CD-8FE6-493A-AB5E-DC1E63F6979F 3031 | 3032 | note 3033 | Get the random note 3034 | xpos 3035 | 1010 3036 | ypos 3037 | 460 3038 | 3039 | 724B20C2-2A71-4470-AA68-E9B53C3E089D 3040 | 3041 | colorindex 3042 | 3 3043 | xpos 3044 | 10 3045 | ypos 3046 | 310 3047 | 3048 | 82C3724E-6E6D-4282-A8D5-F528A6D5A0AE 3049 | 3050 | colorindex 3051 | 3 3052 | xpos 3053 | 10 3054 | ypos 3055 | 2410 3056 | 3057 | 8A5F7A4E-FC3A-466E-A53A-38313E9F8022 3058 | 3059 | note 3060 | Open in default editor 3061 | xpos 3062 | 2210 3063 | ypos 3064 | 910 3065 | 3066 | 8C6B9363-12F2-4E71-8CE7-D1D9777F05C3 3067 | 3068 | note 3069 | Make a donation 3070 | xpos 3071 | 610 3072 | ypos 3073 | 10 3074 | 3075 | 966EB023-178A-428E-B2CB-576954E4A33A 3076 | 3077 | colorindex 3078 | 7 3079 | xpos 3080 | 210 3081 | ypos 3082 | 910 3083 | 3084 | 97B0EE32-A8A1-405E-B0F2-C459AC7FC3E3 3085 | 3086 | xpos 3087 | 1610 3088 | ypos 3089 | 490 3090 | 3091 | 9C2A4DF6-ECF8-45B0-9980-FBE6B1DE2739 3092 | 3093 | note 3094 | Fetch the URL 3095 | xpos 3096 | 1010 3097 | ypos 3098 | 310 3099 | 3100 | A145A5D1-90C7-4FEC-B0F3-8FFE5F6B10D4 3101 | 3102 | note 3103 | Open a random note 3104 | xpos 3105 | 610 3106 | ypos 3107 | 460 3108 | 3109 | A2D9130D-E0ED-4A2F-9D37-4EE26F2B16F9 3110 | 3111 | note 3112 | Create a note 3113 | xpos 3114 | 610 3115 | ypos 3116 | 760 3117 | 3118 | A4A95B3D-BE6A-45BC-A53B-74984F4F48A7 3119 | 3120 | xpos 3121 | 1810 3122 | ypos 3123 | 1665 3124 | 3125 | A73C0944-0E7B-483F-BC14-1A0089887B05 3126 | 3127 | note 3128 | Generate markdown link 3129 | xpos 3130 | 1010 3131 | ypos 3132 | 1510 3133 | 3134 | A8B79535-E3CC-4A12-B1A0-CBE9634E5804 3135 | 3136 | colorindex 3137 | 7 3138 | xpos 3139 | 810 3140 | ypos 3141 | 610 3142 | 3143 | ABB1A2DA-ECDB-4ECF-AAAE-EACF4246706D 3144 | 3145 | colorindex 3146 | 3 3147 | xpos 3148 | 10 3149 | ypos 3150 | 460 3151 | 3152 | B45C99C4-5814-48E9-A8C4-426F939F7335 3153 | 3154 | xpos 3155 | 1810 3156 | ypos 3157 | 1715 3158 | 3159 | B58A48B9-E9D2-46BA-B2FC-8D52D0002AFD 3160 | 3161 | colorindex 3162 | 3 3163 | xpos 3164 | 10 3165 | ypos 3166 | 910 3167 | 3168 | B6D96F39-3BF6-4663-BF58-33CD36A2433D 3169 | 3170 | xpos 3171 | 2410 3172 | ypos 3173 | 460 3174 | 3175 | B78F0AC4-5704-4E41-A5C5-41D7EF829577 3176 | 3177 | xpos 3178 | 810 3179 | ypos 3180 | 1170 3181 | 3182 | BC34D5F9-85CA-4E33-A951-941FE061EEE8 3183 | 3184 | note 3185 | Open donate URL 3186 | xpos 3187 | 2210 3188 | ypos 3189 | 10 3190 | 3191 | BE57B8E8-5E6A-43EC-8087-342FE3342B6C 3192 | 3193 | colorindex 3194 | 3 3195 | xpos 3196 | 10 3197 | ypos 3198 | 1060 3199 | 3200 | C36841B1-1B96-411D-BF40-7B4A70E3AE09 3201 | 3202 | xpos 3203 | 410 3204 | ypos 3205 | 1810 3206 | 3207 | C60A62FF-9B59-4C3C-99F3-807373F2125E 3208 | 3209 | note 3210 | Open in The Archive 3211 | xpos 3212 | 2210 3213 | ypos 3214 | 1060 3215 | 3216 | C767AF6B-DF2C-40A1-8F23-916EDE028F7F 3217 | 3218 | xpos 3219 | 1265 3220 | ypos 3221 | 1690 3222 | 3223 | C813B26C-8583-4087-9E6E-1FAC323A7F0F 3224 | 3225 | note 3226 | Delete note 3227 | xpos 3228 | 2210 3229 | ypos 3230 | 1660 3231 | 3232 | C9B46D25-C13C-4CBC-A087-787CB09B06E5 3233 | 3234 | xpos 3235 | 2410 3236 | ypos 3237 | 310 3238 | 3239 | CB491715-463C-4A1F-BF00-4EF95002AF65 3240 | 3241 | note 3242 | Search tags 3243 | xpos 3244 | 610 3245 | ypos 3246 | 1060 3247 | 3248 | CCFB27EC-FE2A-4853-92F9-66D2E16EC154 3249 | 3250 | xpos 3251 | 750 3252 | ypos 3253 | 790 3254 | 3255 | CE0C3E3D-3480-4860-8AEF-D91987553D48 3256 | 3257 | colorindex 3258 | 7 3259 | xpos 3260 | 1210 3261 | ypos 3262 | 1060 3263 | 3264 | D0A0BB4A-D8DC-4463-A00F-06ABF17CF7F3 3265 | 3266 | xpos 3267 | 1810 3268 | ypos 3269 | 1765 3270 | 3271 | D0E510A1-8928-4339-A865-18534BEB6E01 3272 | 3273 | xpos 3274 | 2410 3275 | ypos 3276 | 1510 3277 | 3278 | D276EC74-1F27-4BA5-97A8-A4E9D1020D2A 3279 | 3280 | note 3281 | Create the note 3282 | xpos 3283 | 1010 3284 | ypos 3285 | 610 3286 | 3287 | D2AD3BCE-73FA-4344-B003-A57E66E4AC6B 3288 | 3289 | xpos 3290 | 1810 3291 | ypos 3292 | 1615 3293 | 3294 | D4A81EE0-15F4-4F07-B5B6-FD9E7646EB3A 3295 | 3296 | xpos 3297 | 805 3298 | ypos 3299 | 790 3300 | 3301 | D6A73E77-7D81-45B7-AC0B-B6E59D5B94DD 3302 | 3303 | note 3304 | Get the note title 3305 | xpos 3306 | 1010 3307 | ypos 3308 | 910 3309 | 3310 | D7113CA2-175F-4D98-B738-A732E4826D02 3311 | 3312 | xpos 3313 | 410 3314 | ypos 3315 | 1210 3316 | 3317 | D7F05A73-355B-4C77-A4F8-F301CF68FB9A 3318 | 3319 | note 3320 | Paste link 3321 | xpos 3322 | 2210 3323 | ypos 3324 | 1360 3325 | 3326 | DBE958B2-368A-48F9-A8AB-1DC9FC300B27 3327 | 3328 | xpos 3329 | 1500 3330 | ypos 3331 | 1690 3332 | 3333 | DE1B8FAF-256C-4AD9-BE4E-9EBCFB71C52D 3334 | 3335 | note 3336 | Create note from an URL 3337 | xpos 3338 | 610 3339 | ypos 3340 | 310 3341 | 3342 | E0CED2B6-51DD-4178-B6BF-5FC59F6EE725 3343 | 3344 | colorindex 3345 | 7 3346 | xpos 3347 | 210 3348 | ypos 3349 | 610 3350 | 3351 | E1BE1374-4C3C-483D-B093-3AFB164AA55A 3352 | 3353 | note 3354 | Open donate URL 3355 | xpos 3356 | 2210 3357 | ypos 3358 | 160 3359 | 3360 | E83305CB-1BAA-457E-93A8-0B9C7689D3C7 3361 | 3362 | colorindex 3363 | 3 3364 | xpos 3365 | 10 3366 | ypos 3367 | 1360 3368 | 3369 | EB8A1BFE-4152-4203-A6B8-DAA827BA4932 3370 | 3371 | xpos 3372 | 1810 3373 | ypos 3374 | 1815 3375 | 3376 | ED18F18E-3DB7-4B1D-A7A3-17DE6EBFA83B 3377 | 3378 | note 3379 | Configure the workflow 3380 | xpos 3381 | 610 3382 | ypos 3383 | 610 3384 | 3385 | EF0769B1-0BDA-4D96-B640-1FA8EB1FD7BB 3386 | 3387 | xpos 3388 | 1150 3389 | ypos 3390 | 640 3391 | 3392 | F2AF7DA9-9371-485E-B037-DF138D6379C1 3393 | 3394 | colorindex 3395 | 3 3396 | xpos 3397 | 10 3398 | ypos 3399 | 760 3400 | 3401 | F2D4CBD3-8C5E-42EE-903C-DDD8ADA6F33B 3402 | 3403 | colorindex 3404 | 3 3405 | xpos 3406 | 10 3407 | ypos 3408 | 2260 3409 | 3410 | F6F03505-7E5B-44D3-9A34-845ABDC79BA1 3411 | 3412 | colorindex 3413 | 3 3414 | xpos 3415 | 10 3416 | ypos 3417 | 1960 3418 | 3419 | FA40A7DB-25B4-464C-B269-EC046612AD60 3420 | 3421 | note 3422 | Copy link 3423 | xpos 3424 | 2210 3425 | ypos 3426 | 1510 3427 | 3428 | FD181211-B1A6-463B-AF31-28A941B28F2E 3429 | 3430 | colorindex 3431 | 7 3432 | xpos 3433 | 1210 3434 | ypos 3435 | 760 3436 | 3437 | 3438 | variables 3439 | 3440 | default_date_format 3441 | %A, %d %B, %Y at %H:%M 3442 | default_zettel_id_format 3443 | %Y%m%d%H%M 3444 | exact_match 3445 | False 3446 | prefer_filename_to_title 3447 | True 3448 | prefer_zettel_id_links 3449 | False 3450 | search_content 3451 | False 3452 | search_yaml_tags_only 3453 | False 3454 | template_tag 3455 | #template 3456 | the_archive_bundle_id 3457 | de.zettelkasten.TheArchive 3458 | the_archive_team_id 3459 | FRMDA3XRGC 3460 | use_zettel_id_in_title 3461 | False 3462 | 3463 | variablesdontexport 3464 | 3465 | version 3466 | 2.0.0 3467 | webaddress 3468 | https://github.com/pryley/alfred-the-archive 3469 | 3470 | 3471 | --------------------------------------------------------------------------------