{"id":13595497,"url":"https://github.com/devidw/obsidian-to-hugo","last_synced_at":"2025-04-04T14:02:46.939Z","repository":{"id":49367292,"uuid":"469095906","full_name":"devidw/obsidian-to-hugo","owner":"devidw","description":"Process Obsidian notes to publish them with Hugo. Supports transformation of Obsidian wiki links into Hugo shortcodes for internal linking.","archived":false,"fork":false,"pushed_at":"2023-03-21T15:45:00.000Z","size":1149,"stargazers_count":370,"open_issues_count":6,"forks_count":29,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T13:03:56.148Z","etag":null,"topics":["blogging","cli","hugo","hugo-helper","obsidian","obsidian-community","obsidian-hugo","obsidian-md","obsidian-notes","obsidian-processor","obsidian-publish","obsidian-vault","obsidianmd","personal-knowledge-management","processing","python","python-cli","replace-text","replacement"],"latest_commit_sha":null,"homepage":"https://obsidian-to-hugo.wolf.gdn","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devidw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-03-12T13:50:25.000Z","updated_at":"2025-03-27T15:08:17.000Z","dependencies_parsed_at":"2024-01-16T22:19:58.850Z","dependency_job_id":"de0b0c11-345a-40ab-9b16-0df9d772da1f","html_url":"https://github.com/devidw/obsidian-to-hugo","commit_stats":{"total_commits":35,"total_committers":5,"mean_commits":7.0,"dds":"0.19999999999999996","last_synced_commit":"7d7e7f04dfea3b2bf87f5562f74ffddf23b1a785"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devidw%2Fobsidian-to-hugo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devidw%2Fobsidian-to-hugo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devidw%2Fobsidian-to-hugo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devidw%2Fobsidian-to-hugo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devidw","download_url":"https://codeload.github.com/devidw/obsidian-to-hugo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182992,"owners_count":20897497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blogging","cli","hugo","hugo-helper","obsidian","obsidian-community","obsidian-hugo","obsidian-md","obsidian-notes","obsidian-processor","obsidian-publish","obsidian-vault","obsidianmd","personal-knowledge-management","processing","python","python-cli","replace-text","replacement"],"created_at":"2024-08-01T16:01:51.188Z","updated_at":"2025-04-04T14:02:46.911Z","avatar_url":"https://github.com/devidw.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003ch1 align=center\u003e\n\u003cimg src=https://raw.githubusercontent.com/devidw/obsidian-to-hugo/master/img/gopher-obsidian.png width=100 height=100\u003e\n\u003cbr\u003e\nObsidian Vault to Hugo Content\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://obsidian-to-hugo.wolf.gdn\" target=\"_blank\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/devidw/obsidian-to-hugo/master/img/demo.gif\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\nLightweight, extensible, zero-dependency CLI written in Python to help us publish [obsidian](https://obsidian.md) notes with [hugo](https://gohugo.io). \n\nIt only takes two arguments: The obsidian vault directory (`--obsidian-vault-dir`) and the hugo content directory (`--hugo-content-dir`).\n\n```console\npython -m obsidian_to_hugo --obsidian-vault-dir=\u003cpath\u003e --hugo-content-dir=\u003cpath\u003e\n```\n\nIt takes care of the following steps:\n\n- Clears hugo content directory (directory will be deleted and recreated)\n- Copies obsidian vault contents into hugo content directory (`.obsidian` gets removed immediately after copying)\n- Replaces obsidian wiki links (`[[wikilink]]`) with hugo shortcode links\n  (`[wikilink]({{\u003c ref \"wikilink\" \u003e}})`)\n- Replaces obsidian marks (`==important==`) with HTML marks (`\u003cmark\u003eimportant\u003c/mark\u003e`)\n- Want to do more? You can write and register custom [filters](#filters) to dynamically\n  include/exclude content from processing and [processors](#processors) to do whatever\n  you want with the file contents.\n\n\n## Replacement examples\n\n| Obsidian | Hugo\n| -------- | --------\n| ![](https://raw.githubusercontent.com/devidw/obsidian-to-hugo/master/img/obsidian.png) | ![](https://raw.githubusercontent.com/devidw/obsidian-to-hugo/master/img/hugo.png)\n| `[[/some/wiki/link]]` | `[/some/wiki/link]({{\u003c ref \"/some/wiki/link\" \u003e}})`\n| `[[/some/wiki/link\\|Some text]]` | `[Some text]({{\u003c ref \"/some/wiki/link\" \u003e}})`\n| `[[/some/wiki/link/_index]]` | `[/some/wiki/link/]({{\u003c ref \"/some/wiki/link/\" \u003e}})`\n| `[[/some/wiki/link#Some Heading\\|Some Heading Link]]` | `[Some Heading Link]({{\u003c ref \"/some/wiki/link#some-heading\" \u003e}})`\n| `==foo bar===` | `\u003cmark\u003efoo bar\u003c/mark\u003e`\n\n\u003e **Note**\n\u003e For now, there is *no way to escape* obsidian wiki links. Every link\n\u003e will be replaced with a hugo link. The only way to get around this is changing\n\u003e the wiki link to don't match the exact sytax, for example by adding an\n\u003e [invisible space](https://en.wikipedia.org/wiki/Zero-width_space) (Obsidian will highlight the invisible character as a red dot).\n\u003e ![](https://raw.githubusercontent.com/devidw/obsidian-to-hugo/master/img/do-not-do-that.png)\n\u003e However, this still is really really *not* best\n\u003e practice, so if anyone wants to implement real escaping, [please do\n\u003e so](https://github.com/devidw/obsidian-to-hugo/pulls).\n\n\n## Installation\n\n```console\npip install obsidian-to-hugo\n```\n\n\n## Usage\n\n```console\nusage: __main__.py [-h] [--version] [--hugo-content-dir HUGO_CONTENT_DIR]\n                   [--obsidian-vault-dir OBSIDIAN_VAULT_DIR]\n\noptions:\n  -h, --help            show this help message and exit\n  --version, -v         Show the version and exit.\n  --hugo-content-dir HUGO_CONTENT_DIR\n                        Directory of your Hugo content directory, the obsidian notes\n                        should be processed into.\n  --obsidian-vault-dir OBSIDIAN_VAULT_DIR\n                        Directory of the Obsidian vault, the notes should be processed\n                        from.\n```\n\n## Python API\n\n```python\nfrom obsidian_to_hugo import ObsidianToHugo\n\nobsidian_to_hugo = ObsidianToHugo(\n    obsidian_vault_dir=\"path/to/obsidian/vault\",\n    hugo_content_dir=\"path/to/hugo/content\",\n)\n\nobsidian_to_hugo.run()\n```\n\n\n### Filters\n\nYou can pass an optional `filters` argument to the `ObsidianToHugo`\nconstructor. This argument should be a list of functions.\n\nThe function will be invoked for each file from the obsidian vault that is\ncopied into the hugo content directory.\n\nInside the function, you have access to the file path and the file contents.\n\nWhen the function returns `False`, the file will be skipped and not copied\ninto the hugo content directory.\n\n```python\nfrom obsidian_to_hugo import ObsidianToHugo\n\ndef filter_file(file_contents: str, file_path: str) -\u003e bool:\n    # do something with the file path and contents\n    if your_condition:\n        return True # copy file\n    else:\n        return False # skip file\n\nobsidian_to_hugo = ObsidianToHugo(\n    obsidian_vault_dir=\"path/to/obsidian/vault\",\n    hugo_content_dir=\"path/to/hugo/content\",\n    filters=[filter_file],\n)\n\nobsidian_to_hugo.run()\n```\n\n\n### Processors\n\nYou can pass an optional `processors` argument to the `ObsidianToHugo`\nconstructor. This argument should be a list of functions.\n\nThe function will be invoked for each file from the obsidian vault that is\ncopied into the hugo content directory. It will be passed the file contents\nas string, and should return the processed version of the file contents.\n\nCustom processors are invoked after the default processing of the file contents.\n\n```python\nfrom obsidian_to_hugo import ObsidianToHugo\n\ndef process_file(file_contents: str) -\u003e str:\n    # do something with the file contents\n    return file_contents\n\nobsidian_to_hugo = ObsidianToHugo(\n    obsidian_vault_dir=\"path/to/obsidian/vault\",\n    hugo_content_dir=\"path/to/hugo/content\",\n    processors=[process_file],\n)\n\nobsidian_to_hugo.run()\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevidw%2Fobsidian-to-hugo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevidw%2Fobsidian-to-hugo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevidw%2Fobsidian-to-hugo/lists"}