├── .gitignore ├── .obsidian ├── hotkeys.json ├── app.json ├── appearance.json ├── core-plugins.json └── workspace ├── .env ├── Jekyll.md ├── Obsidian Blog Project.md ├── Obsidian Blog Documentation Vault.md ├── Handlebars Templates.md ├── Posts Sorting.md ├── Posts └── Test.md ├── Templates.md ├── Dev Mode.md ├── Installation.md ├── Assets Processing.md ├── Inlined Note.md ├── Config Context.md ├── Features.md ├── Pages ├── index.md └── all_posts.hbs ├── Headings Generation.md ├── Further Reading Section.md ├── README.md ├── Image Context.md ├── Global Context.md ├── Notes Parsing.md ├── .blog ├── _layouts │ ├── simple.hbs │ └── main.hbs └── _assets │ └── styles.css ├── Privacy.md ├── Images.md ├── Notes Linkification.md ├── Title Detection.md ├── Usage.md ├── .github └── workflows │ └── publish.yml ├── Intro.md ├── Directory Structure.md ├── LICENSE ├── Settings.md ├── Pages.md ├── Deployment.md └── Layouts.md /.gitignore: -------------------------------------------------------------------------------- 1 | .build 2 | -------------------------------------------------------------------------------- /.obsidian/hotkeys.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | blog_title="Obsidian Blog. SSG for Obsidian" 2 | -------------------------------------------------------------------------------- /.obsidian/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "alwaysUpdateLinks": true 3 | } -------------------------------------------------------------------------------- /.obsidian/appearance.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseFontSize": 16 3 | } -------------------------------------------------------------------------------- /Jekyll.md: -------------------------------------------------------------------------------- 1 | --- 2 | link: https://jekyllrb.com/ 3 | --- 4 | -------------------------------------------------------------------------------- /Obsidian Blog Project.md: -------------------------------------------------------------------------------- 1 | --- 2 | link: https://github.com/A/obsidian-blog 3 | --- 4 | -------------------------------------------------------------------------------- /Obsidian Blog Documentation Vault.md: -------------------------------------------------------------------------------- 1 | --- 2 | link: https://github.com/A/obsidian-blog-theme 3 | --- 4 | -------------------------------------------------------------------------------- /Handlebars Templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Both posts and pages are post-processed by `handlebars`. 6 | -------------------------------------------------------------------------------- /Posts Sorting.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Posts are sorted by `date` attribute in the frontmatters section 6 | -------------------------------------------------------------------------------- /Posts/Test.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test Page 3 | published: True 4 | slug: tst 5 | date: 2022-02-05 6 | --- 7 | 8 | Just a hello world post 9 | 10 | -------------------------------------------------------------------------------- /Templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | [[Global Context]] 6 | [[Config Context]] 7 | [[Layouts]] 8 | [[Pages]] 9 | [[Images]] 10 | 11 | -------------------------------------------------------------------------------- /Dev Mode.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Dev mode is useful to write and check your drafts locally: 6 | 7 | ``` 8 | obsidian-blog -dws 9 | ``` 10 | -------------------------------------------------------------------------------- /Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installation 3 | published: True 4 | 5 | --- 6 | The simplest way is to run: 7 | 8 | ``` 9 | pip install obsidian-blog 10 | ``` 11 | -------------------------------------------------------------------------------- /Assets Processing.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | During the build, `obsidian-blog` takes all local files used in your posts and pages, copies them into `.build` directory and updates their links accordingly. 6 | -------------------------------------------------------------------------------- /Inlined Note.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Global Context 3 | published: True 4 | --- 5 | 6 | ## This is an Inlined Note 7 | 8 | Have fun combining notes from your vault to make a good content. 9 | 10 | ![[Lets Go.jpg]] 11 | -------------------------------------------------------------------------------- /Config Context.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | links: 4 | - name: Config Data 5 | url: https://github.com/A/obsidian-blog/blob/master/src/dataclasses/config_data.py 6 | --- 7 | 8 | Config is passed to handlebars templates as `config` variable. 9 | 10 | -------------------------------------------------------------------------------- /Features.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | [[Notes Parsing]] 6 | [[Assets Processing]] 7 | 8 | [[Headings Generation]] 9 | 10 | [[Handlebars Templates]] 11 | [[Privacy]] 12 | [[Title Detection]] 13 | [[Dev Mode]] 14 | [[Further Reading Section]] 15 | [[Notes Linkification]] 16 | -------------------------------------------------------------------------------- /Pages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Obsidian Blog Manual 3 | published: True 4 | date: 2021-01-09 5 | layout: main 6 | --- 7 | 8 | ![[Intro]] 9 | ![[Installation]] 10 | ![[Usage]] 11 | ![[Directory Structure]] 12 | ![[Settings]] 13 | ![[Features]] 14 | 15 | ![[Templates]] 16 | ![[Deployment]] 17 | 18 | -------------------------------------------------------------------------------- /.obsidian/core-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "file-explorer", 3 | "global-search", 4 | "switcher", 5 | "graph", 6 | "backlink", 7 | "page-preview", 8 | "note-composer", 9 | "command-palette", 10 | "editor-status", 11 | "markdown-importer", 12 | "word-count", 13 | "open-with-default-app", 14 | "file-recovery" 15 | ] -------------------------------------------------------------------------------- /Headings Generation.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | `obsidian-blog` renders a header with note `title` for each note with a non-empty content. This header has `id` attribute and can be used as an anchor. 6 | 7 | As it was mentioned before, there are plenty of ways to define titles, and you can even skip it to use filename instead. 8 | -------------------------------------------------------------------------------- /Pages/all_posts.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: All Posts 3 | published: True 4 | layout: simple 5 | --- 6 | 7 | 16 | -------------------------------------------------------------------------------- /Further Reading Section.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | links: 4 | - name: Example 5 | url: https://example.com 6 | --- 7 | 8 | If a note has `links` list in the frontmatter, this links will be rendered just under the note as the Further Reading block 9 | 10 | ``` 11 | links: 12 | - name: Example 13 | url: https://example.com 14 | ``` 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Obsidian Blog Theme Example 2 | 3 | This is a pretty simple site contains documentation for [`obsidian-blog`][obsidian-blog] static site generator. 4 | 5 | To check the documentation go here [obsidian-blog.anto.sh][obsidian-blog-docs] 6 | 7 | [obsidian-blog]: https://github.com/A/obsidian-blog 8 | [obsidian-blog-docs]: https://obsidian-blog.anto.sh 9 | -------------------------------------------------------------------------------- /Image Context.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Image Context 3 | published: True 4 | --- 5 | 6 | Images are part of a `post_context` and may be accessible in templates from `post.imgs` list. 7 | 8 | ``` 9 | { 10 | "file": str, 11 | "slug": str, # generated from the sluggified filename 12 | "name": str, # generated from the filename 13 | "placeholder": str, # mediawiki image placeholder like ![[Image.png]] 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /Global Context.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Global Context 3 | published: True 4 | --- 5 | 6 | `global_context` is always accessible in all handlebars templates (layouts, pages) and includes few variables: 7 | 8 | ``` 9 | { 10 | "config": Config 11 | "self": Page, # refers to the active page 12 | "layouts": dict[str, Layout], 13 | "posts": list[Page], # list of posts 14 | "pages": list[Page], # list of pages 15 | }) 16 | ``` 17 | -------------------------------------------------------------------------------- /Notes Parsing.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Parser starts at 2 main directories: `Pages` and `Posts`. It recursively processes all embedded notes if they are placed on the new line and don't have any text around. Parser also supports cycles detection, and shouldn't fail in this case. 6 | 7 | Parser recursively collects all entities (such as images, notes, links, etc) from your posts and pages and build a flat list of them. 8 | -------------------------------------------------------------------------------- /.blog/_layouts/simple.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{self.title}} 5 | 6 | 7 | 8 |
9 |
10 |

{{self.title}}

11 | {{{ content }}} 12 |
13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /Privacy.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | `obsidian-blog` don't publish anything explicitly marked as published in the frontmatter section: 6 | 7 | ``` 8 | --- 9 | published: True 10 | --- 11 | ``` 12 | 13 | Non-published notes are still being parsed, but ignored during the rendering. 14 | 15 | There is also the draft feature. You can annotate your post `draft: True` to make it visible if you start `obsidian-blog` with the `--drafts` flag. 16 | -------------------------------------------------------------------------------- /Images.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Images 3 | published: True 4 | --- 5 | 6 | Images are processed in 2 steps: 7 | 8 | ### Parsing 9 | 10 | All images are parsed into `asset_entity` objects contains their placeholders, alts, and urls. 11 | 12 | ### Building 13 | 14 | During the build image files are copied under `.build` dir, and urls are updated accordingly. Then images are rendered into HTML. 15 | 16 | To point to a specific image, use `config.public_dir` prefix in a handlebars template. 17 | -------------------------------------------------------------------------------- /Notes Linkification.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Another opinionated thing: `obsidian-blog` doesn't consider obsidian links that has text around as notes that should be unwrapped into the post. It seems natural (at least for me), that this links should be processed as links. 6 | `obsidian-blog` checks if the notes have `link` attribute in the frontmatter section, and if they do, it replaces this includes as old good html links. 7 | 8 | That's really useful on a large vault, when you links to a MoC in a specific note, and you don't want the whole MoC to be populated into your post. 9 | -------------------------------------------------------------------------------- /Title Detection.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | `obsidian-blog` has a title-detection mechanism: 6 | 7 | 1. If note was included with inline title like `[[this | one]]`, the `one` will be a title 8 | 2. If note has a `title` attribute in the frontmatter section, it will be used. 9 | 3. Otherwise a filename will be used as a title. 10 | 11 | ### Filename Title Delimeters 12 | 13 | If note has no other title then a filename, and filename contains the delimeter (` - `), the rightest section will be used as a title. This helps if you name your notes with a category prefix, like `Prometheus - PromQL Selectors.md` becomes `PromQL Selectors`. It's a bit opinionated, but this convention saves time. 14 | -------------------------------------------------------------------------------- /Usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | The simplest way to start so far is to copy `.blog` dir from [this repository][obsidian-blog-theme] and tweak css and templates to fit your design. 6 | 7 | 8 | ### Writing 9 | 10 | For writing purpose, you can start `obsidian-blog` to watch and serve mode: 11 | 12 | ``` 13 | obsidian-blog --serve --watch 14 | ``` 15 | 16 | This one will start a simple http server on the `localhost:4200` and rebuild your content on any change. 17 | 18 | 19 | ### Building 20 | 21 | To build your notes into the static files just run `obsidian-blog` command. Static site will be in the `.build` directory. 22 | 23 | [obsidian-blog-theme]: https://github.com/A/obsidian-blog-theme/tree/master/.blog 24 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Deploy GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - "master" 7 | 8 | env: 9 | PYTHON_VERSION: 3.10.15 10 | 11 | jobs: 12 | build-and-deploy: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: actions/setup-python@v2 17 | with: 18 | python-version: ${{ env.PYTHON_VERSION }} 19 | - name: install obsidian-blog 20 | run: pip install obsidian-blog 21 | 22 | - name: build static site 23 | run: obsidian-blog 24 | 25 | - name: Add gh-pages CNAME 26 | run: echo ${{ secrets.CNAME }} > .build/CNAME 27 | 28 | - uses: JamesIves/github-pages-deploy-action@4.1.4 29 | with: 30 | branch: gh-pages 31 | folder: .build 32 | -------------------------------------------------------------------------------- /Intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Intro 3 | published: True 4 | --- 5 | 6 | `obsidian-blog` is a simple static site generator inspired by [[Jekyll]] and written in Python. It allows you to use your atomic notes to compile static pages and posts as [MoCs][moc]. Sounds interesting, isn't it? 7 | 8 | Need to mention, `obsidian-blog` is not a one-click-ready-to-go blog. It requires some basic codding skills to tinker a bit with [handlebars][handlebars] and css to cook what you need. 9 | 10 | - [[Obsidian Blog Project]] 11 | - [[Obsidian Blog Documentation Vault]] 12 | 13 | [obsidian]: https://obsidian.md/ 14 | [jekyll]: https://jekyllrb.com/ 15 | [moc]: https://www.youtube.com/watch?v=7GqQKCT0PZ4 16 | [zettelkasten]: https://en.wikipedia.org/wiki/Niklas_Luhmann#Note-taking_system_(Zettelkasten) 17 | [handlebars]: https://handlebarsjs.com/ 18 | -------------------------------------------------------------------------------- /Directory Structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Directory Structure 3 | published: True 4 | --- 5 | 6 | ### Directory Structure 7 | 8 | The first thing you need to do is to create a `_blog` directory in the root of your vault with a structure like on the listing below. The simplest way is to copy it from this example vault. 9 | 10 | ``` 11 | _blog 12 | ├── Post.md 13 | ├── _assets 14 | │   └── styles.css 15 | ├── _layouts 16 | │   └── main.hbs 17 | └── _pages 18 | ├── about.hbs 19 | └── index.hbs 20 | ``` 21 | 22 | Let me briefly explain each directory inside of `_blog`: 23 | 24 | - `_assets` are static files, such as `css`, `js` or images are always being copied into resulting build. 25 | - `_layouts` is a room for handlebars layout files. You can specify different layouts for diferent pages and posts by setting `layout: ` in the [yaml-frontmatter][frontmatter] part of the file. 26 | - `_pages` is where handlebars page templates live. Like `about`, `contacts`, `all-posts`, `my cv` and so on. 27 | 28 | Note, that there is no `posts` directory, because, all your posts lives right inside the `_blog` directory. 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Shuvalov Anton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | `obsidian-blog` supports `.env`, and it seems a pretty good place to define your `blog_title` and other specific settings. A list of variables is [here][obsidian-blog-config]. 6 | 7 | Another way is to use cli flags. Take a look on `obsidian-blog --help` for a list of supported options: 8 | 9 | ``` 10 | notes ❯ obsidian-blog --help 11 | obsidian-blog 12 | 13 | Static site generator for obsidian.md notes. 14 | 15 | Usage: 16 | obsidian-blog [-d] [-w] [-s] [--port ] [--title ] [--posts_dir ] [--pages_dir ] 17 | 18 | Options: 19 | -h --help Show this screen. 20 | -w --watch Enable watcher 21 | -s --serve Enable web-server 22 | -p --port= Web-server port [default: 4200] 23 | -d --drafts Render draft pages and posts 24 | 25 | --title= Blog title [default: My Blog] 26 | 27 | --version Show version. 28 | ``` 29 | 30 | [obsidian-blog-config]: https://github.com/A/obsidian-blog/blob/master/src/dataclasses/config_data.py#L7 31 | -------------------------------------------------------------------------------- /.blog/_layouts/main.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{self.title}} 5 | 6 | 7 | 8 |
9 |
10 | {{#if self.entities}} 11 |

12 | Table of Content 13 |

14 | 25 | {{/if}} 26 |
27 | 28 |
29 |

{{self.title}}

30 | {{{ content }}} 31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /Pages.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Active Page Context 3 | published: True 4 | links: 5 | - name: Content Data Implementation 6 | url: https://github.com/A/obsidian-blog/blob/master/src/dataclasses/content_data.py 7 | --- 8 | 9 | To get some data from the current page rendered in a handlebars template, you can refere to `self` variable, which has properties listed below: 10 | 11 | - `self.content` refers to the rendered html content of the page 12 | - `self.entities` refers to the list of entities parsed from a page and its children. That's useful to render ToCs, etc 13 | - `self.title` 14 | - `self.date` 15 | - `self.slug` is a path after `/` the page is published to 16 | - `self.meta` is a dict contains frontmatter variables of the page 17 | 18 | Pages are handlebars templates support a yaml-frontmatter section. Pages stands for anything but posts. 19 | 20 | This is an example of `index.hbs` page renders all posts from the blog: 21 | 22 | ```handlebars 23 | --- 24 | title: Posts 25 | --- 26 |

{{ self.title }}

27 |
35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /Deployment.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | links: 4 | - name: GitHub Actions Documentation 5 | url: https://docs.github.com/en/actions 6 | - name: Managing a custom domain for your GitHub Pages site 7 | url: https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site 8 | --- 9 | 10 | It's quite easy to build and deploy a static site to your own domain: 11 | 12 | ``` 13 | name: Deploy GitHub Pages 14 | 15 | on: 16 | push: 17 | branches: 18 | - "master" 19 | 20 | env: 21 | PYTHON_VERSION: 3.10.2 22 | 23 | jobs: 24 | build-and-deploy: 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v2 28 | - uses: actions/setup-python@v2 29 | with: 30 | python-version: ${{ env.PYTHON_VERSION }} 31 | - name: install obsidian-blog 32 | run: pip install obsidian-blog 33 | 34 | - name: build static site 35 | run: obsidian-blog 36 | 37 | - name: Add gh-pages CNAME 38 | run: echo ${{ secrets.DOMAIN }} > .build/CNAME 39 | 40 | - uses: JamesIves/github-pages-deploy-action@4.1.4 41 | with: 42 | branch: gh-pages 43 | folder: .build 44 | ``` 45 | -------------------------------------------------------------------------------- /Layouts.md: -------------------------------------------------------------------------------- 1 | --- 2 | published: True 3 | --- 4 | 5 | Layouts are old good handlebars layouts compiled with a `global_context` and `page_context` or `post_context` accordingly. There is a simple example layout renders links to all pages and a content. 6 | 7 | ```html 8 | 9 | 10 | 11 | 12 | 13 | {{ self.title }} 14 | 15 | 16 | 17 |

18 | {{ config.blog_title }} 19 |

20 | 29 |
30 |
31 | {{{ content }}} 32 |
33 |
34 | 35 | 36 | ``` 37 | 38 | In a post or a page, you can specify which one you'd like to use to render the content within the yaml-frontmatter block: 39 | 40 | ``` 41 | --- 42 | title: Hello World 43 | date: 2021-01-09 44 | layout: main 45 | --- 46 | ``` 47 | 48 | If layout is not specified, `main` will be used as default one. 49 | -------------------------------------------------------------------------------- /.blog/_assets/styles.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | padding: 0; 3 | margin: 0; 4 | width: 100%; 5 | height: 100%; 6 | overflow: hidden; 7 | } 8 | 9 | body { 10 | padding: 1rem; 11 | } 12 | 13 | * { 14 | box-sizing: border-box; 15 | } 16 | 17 | :root { 18 | --content-max-width: 800px; 19 | --content-horizontal-paddings: 2rem; 20 | --sidebar-max-width: 240px; 21 | --page-max-width: 1600px; 22 | --breakpoints-mobile: calc(var(--content-max-width) + var(--sidebar-max-width) * 2); 23 | } 24 | 25 | .page { 26 | display: flex; 27 | flex-direction: row; 28 | justify-content: space-between; 29 | padding: 0; 30 | margin: 0 auto; 31 | height: 100%; 32 | max-width: var(--page-max-width); 33 | overflow: hidden; 34 | } 35 | 36 | .page__pages-list, 37 | .page__table-of-content { 38 | min-width: var(--sidebar-max-width); 39 | overflow-y: scroll; 40 | font-size: 0.8rem; 41 | } 42 | 43 | .page__pages-list { 44 | order: 1; 45 | } 46 | .page__table-of-content { 47 | order: 3; 48 | } 49 | .page__content { 50 | order: 2; 51 | max-width: var(--content-max-width); 52 | width: 100%; 53 | overflow-y: scroll; 54 | padding: 0 var(--content-horizontal-paddings); 55 | } 56 | 57 | .pages-list__header {} 58 | .pages-list__list {} 59 | .pages-list__item {} 60 | .pages-list__item-link {} 61 | 62 | .table-of-content__header {} 63 | .table-of-content__header-link {} 64 | .table-of-content__item {} 65 | .table-of-content__item-link {} 66 | 67 | 68 | .page__content img { 69 | width: 100%; 70 | background: white; 71 | padding: 2rem; 72 | } 73 | 74 | .page__content hr { 75 | border: none; 76 | margin: 0; 77 | padding: 0; 78 | text-align: center; 79 | } 80 | 81 | .page__content hr:after { 82 | display: inline-block; 83 | content: '---'; 84 | color: var(--text-color); 85 | opacity: .5; 86 | } 87 | 88 | hr + hr { 89 | display: none; 90 | } 91 | 92 | @media (prefers-color-scheme: dark) { 93 | html { 94 | filter: invert() hue-rotate(200deg); 95 | background: white; 96 | } 97 | 98 | .page__content img { 99 | filter: invert() hue-rotate(-200deg); 100 | } 101 | } 102 | 103 | @media only screen and (max-width: 1240px) { 104 | .page { 105 | flex-direction: column; 106 | justify-content: normal; 107 | overflow-y: unset; 108 | } 109 | 110 | .page__table-of-content, 111 | .page__content, 112 | .page__pages-list { 113 | overflow-y: unset; 114 | } 115 | 116 | .page__table-of-content { 117 | order: 1; 118 | } 119 | 120 | .page__content { 121 | order: 2; 122 | max-width: 100%; 123 | } 124 | } 125 | 126 | pre { 127 | width: 100%; 128 | overflow-x: scroll; 129 | } 130 | -------------------------------------------------------------------------------- /.obsidian/workspace: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "id": "32138ae8009d4e13", 4 | "type": "split", 5 | "children": [ 6 | { 7 | "id": "5186b5e49fcab318", 8 | "type": "leaf", 9 | "dimension": 50.19230769230769, 10 | "state": { 11 | "type": "markdown", 12 | "state": { 13 | "file": "Usage Example.md", 14 | "mode": "source" 15 | } 16 | } 17 | }, 18 | { 19 | "id": "66d2fa6b42696d9f", 20 | "type": "leaf", 21 | "dimension": 49.80769230769231, 22 | "state": { 23 | "type": "markdown", 24 | "state": { 25 | "file": "Pages Context.md", 26 | "mode": "source" 27 | } 28 | } 29 | } 30 | ], 31 | "direction": "vertical" 32 | }, 33 | "left": { 34 | "id": "630fc53bd6bead34", 35 | "type": "split", 36 | "children": [ 37 | { 38 | "id": "d3de7a8113b2c059", 39 | "type": "tabs", 40 | "children": [ 41 | { 42 | "id": "71f0679fc1e3ba14", 43 | "type": "leaf", 44 | "state": { 45 | "type": "file-explorer", 46 | "state": {} 47 | } 48 | }, 49 | { 50 | "id": "de8ab5dfcf0a6ddf", 51 | "type": "leaf", 52 | "state": { 53 | "type": "search", 54 | "state": { 55 | "query": "", 56 | "matchingCase": false, 57 | "explainSearch": false, 58 | "collapseAll": false, 59 | "extraContext": false, 60 | "sortOrder": "alphabetical" 61 | } 62 | } 63 | } 64 | ] 65 | } 66 | ], 67 | "direction": "horizontal", 68 | "width": 300 69 | }, 70 | "right": { 71 | "id": "bc889e06f702653d", 72 | "type": "split", 73 | "children": [ 74 | { 75 | "id": "e54c13610bc65f36", 76 | "type": "tabs", 77 | "children": [ 78 | { 79 | "id": "1f3aae00729c9300", 80 | "type": "leaf", 81 | "state": { 82 | "type": "backlink", 83 | "state": { 84 | "file": "Usage Example.md", 85 | "collapseAll": false, 86 | "extraContext": false, 87 | "sortOrder": "alphabetical", 88 | "showSearch": false, 89 | "searchQuery": "", 90 | "backlinkCollapsed": false, 91 | "unlinkedCollapsed": true 92 | } 93 | } 94 | } 95 | ] 96 | } 97 | ], 98 | "direction": "horizontal", 99 | "width": 300, 100 | "collapsed": true 101 | }, 102 | "active": "5186b5e49fcab318", 103 | "lastOpenFiles": [ 104 | "Usage Example.md", 105 | "_blog/Hello World.md", 106 | "Live Updates.md", 107 | "Global Context.md", 108 | "Image Context.md", 109 | "Images.md", 110 | "Posts Context.md", 111 | "Posts.md", 112 | "Pages Context.md", 113 | "Pages.md" 114 | ] 115 | } --------------------------------------------------------------------------------