#!/usr/bin/env python3 """ # Script ob-snippets ## Metadata **Kind**: #obsidian/ob-script **Language**: #python **Parent**:: [[Obsidian Chore Scripts]], [[Executable Markdown File]] ## Synopsis I use LuaSnip for snippets expansion. This script export the snippets to Obsidian. Example:: [[Snippets - Obsidian]] ## Script ```python # """ from collections import defaultdict from pathlib import Path import filecmp import os import tempfile import json import itertools SYNTAX_MAP = { 'Anki': 'html', 'Bats': 'shell', 'CKB': 'markdown', 'Console': 'shell', 'CriticMarkup': 'markdown', 'Cryptape': 'markdown', 'Deckset': 'markdown', 'Envrc': 'shell', 'Git': 'markdown', 'GitHub Actions': 'yaml', 'GitHub ID': 'markdown', 'GitHub': 'markdown', 'Global': '', 'HTML': 'html', 'IdeaVim': 'vim', 'Java': 'java', 'Markdown': 'markdown', 'Mirror': 'shell', 'Nerd Font': '', 'Obsidian': 'markdown', 'Parallels': 'ruby', 'Pass': '', 'PowerShell': 'powershell', 'Profile': '', 'Projections': 'json', 'Prompt': 'markdown', 'Proxy': 'shell', 'Python': 'python', 'Rust': 'rust', 'SQL': 'sql', 'SSH': '', 'Shell': 'shell', 'Signature': 'markdown', 'Snippet': '', 'Sudo': '', 'Symbols': '', 'Tmux': 'shell', 'Unreal': 'cpp', 'Vim': 'vim', 'Wiki': 'wiki', } PUBLISH = { 'CKB': False, 'Cryptape': False, 'GitHub ID': False, } def collect_snippets_in_file(file): snippets = json.load(file.open()) for name, snippet in snippets.items(): name_parts = name.split(' ➤ ', maxsplit=1) if len(name_parts) == 2: category, name = name_parts else: category = "Global" snippet['category'] = category snippet['name'] = name yield snippet def collect_snippets_in_directory(directory): for root, _, files in os.walk(directory): root = Path(root) for file in files: if file == 'global.code-snippets' or file.endswith('.json'): yield from collect_snippets_in_file(root / file) abbrev_file = Path.home() / '.dotfiles' / 'repos' / 'public' / \ 'nvim' / 'plugin' / 'iy-public-init.vim' for line in abbrev_file.open().readlines(): if line.startswith('noreabbrev vv'): prefix, body = line.split()[1:] snippet = { 'name': prefix[2:], 'category': 'Symbols', 'prefix': prefix, 'body': [body] } yield snippet def categorize_snippets(snippets): categories = defaultdict(list) for snippet in snippets: categories[snippet['category']].append(snippet) return categories def save_categories(categories, directory): index_page_lines = [ '# ♯ Snippets Library\n', ] for category, snippets in sorted(categories.items()): index_page_lines.append( f'- [[Snippets - {category}|{category}]] ({len(snippets)})') syntax = SYNTAX_MAP[category] with open(directory / f'Snippets - {category}.md', 'w', newline="\n") as fout: publish = 'true' if PUBLISH.get(category, True) else 'false' print(f'---\npublish: {publish}', file=fout) if syntax != '': print(f'syntax: {syntax}', file=fout) print(f'---\n# Snippets - {category}', file=fout) print('\n**Kind**:: #snippets-collection', file=fout) print('**Source**:: #from/vsnip', file=fout) print('**Generated by**:: [[ob-snippets]]', file=fout) print(f'**Snippets**:: {len(snippets)}', file=fout) for snippet in snippets: print( f'\n## {snippet["name"]} (`{snippet["prefix"]}`)\n', file=fout) if 'description' in snippet: print(snippet['description'], file=fout) print('', file=fout) print(f'```{syntax}', file=fout) print('\n'.join(snippet["body"]), file=fout, end='') print('\n```', file=fout) with open(directory / '♯ Snippets Library.md', 'w', newline="\n") as fout: print('\n'.join(index_page_lines), file=fout) def main(): repos_dir = Path.home() / '.dotfiles' / 'repos' pub_snips_dir = repos_dir / 'public' / 'nvim' / 'snippets' priv_snips_dir = repos_dir / 'private' / 'nvim' / 'snippets' pub_snippets = collect_snippets_in_directory(pub_snips_dir) priv_snippets = collect_snippets_in_directory(priv_snips_dir) categories = categorize_snippets( itertools.chain(pub_snippets, priv_snippets)) tmp_dir = Path(tempfile.mkdtemp()) save_categories(categories, tmp_dir) export_dir = Path('robot') / 'Snippets Library' for root, _, files in os.walk(tmp_dir): for f in files: src_file = Path(root) / f relative_path = src_file.relative_to(tmp_dir) target_file = export_dir / relative_path target_file.parent.mkdir(exist_ok=True) is_new = not target_file.exists() or not filecmp.cmp( src_file, target_file, shallow=False ) if is_new: print('NEW:', relative_path) os.replace(src_file, target_file) else: # print('SKIP:', relative_path) pass if __name__ == '__main__': main() """ # vim: ft=python ``` """