#!/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",
"TLA": "tla",
}
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
```
"""