├── .all-contributorsrc ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE.md ├── changelog-configuration.json ├── dependabot.yml ├── labeler.yml └── workflows │ ├── deploy-clean.yml │ ├── history-clean.yml │ ├── issues-accept.yml │ ├── issues-new.yml │ ├── issues-scan.yml │ ├── issues-stale.yml │ ├── labels-clean.yml │ ├── labels-create.yml │ ├── ping-developer.yml │ └── release.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Snippets ├── Alphabetized List 1 │ ├── README.md │ └── images │ │ ├── example_1.gif │ │ ├── example_2.gif │ │ ├── example_3.gif │ │ ├── example_4.gif │ │ ├── example_5.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif ├── Alphabetized List 2 │ └── code.txt ├── Bad Links 1 │ ├── README.md │ └── images │ │ ├── example_1.png │ │ ├── example_2.gif │ │ ├── example_3.gif │ │ ├── example_4.gif │ │ ├── example_5.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif ├── Page Cloud 1 │ ├── README.md │ └── images │ │ ├── example_1.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ ├── install_3.gif │ │ └── install_4.gif ├── Subfolder Data │ ├── README.md │ ├── images │ │ ├── example_1.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif │ └── snippet-version3 ├── TOC Version 1 │ ├── README.md │ └── images │ │ ├── example_1.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif ├── TOC Version 2 │ ├── README.md │ └── images │ │ ├── example_1.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif ├── Tag Cloud 1 │ ├── README.md │ └── images │ │ ├── example_1.gif │ │ ├── install_1.gif │ │ ├── install_2.png │ │ └── install_3.gif └── Tag Cloud 2 │ ├── README.md │ └── images │ ├── example_1.gif │ ├── install_1.gif │ ├── install_2.png │ ├── install_3.gif │ └── install_4.gif ├── eslint.config.js ├── obs.js ├── package-lock.json └── package.json /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "obsidian-dataview-snippets", 3 | "projectOwner": "Aetherinox", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": ["README.md"], 7 | "imageSize": 40, 8 | "commit": true, 9 | "commitConvention": "angular", 10 | "contributors": [ 11 | { 12 | "login": "Aetherinox", 13 | "name": "Aetherinox", 14 | "avatar_url": "https://avatars.githubusercontent.com/u/118329232?v=4", 15 | "profile": "https://gitlab.com/Aetherinox", 16 | "contributions": ["code", "projectManagement"] 17 | } 18 | ], 19 | "contributorsPerLine": 5, 20 | "linkToUsage": false 21 | } 22 | 23 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | # # 4 | # is top-most EditorConfig file 5 | # # 6 | 7 | root = true 8 | 9 | # # 10 | # All Files 11 | # # 12 | 13 | [*] 14 | indent_style = space 15 | indent_size = 4 16 | end_of_line = lf 17 | charset = utf-8 18 | trim_trailing_whitespace = true 19 | insert_final_newline = true 20 | 21 | # # 22 | # Markdown Files 23 | # # 24 | 25 | [*.md] 26 | trim_trailing_whitespace = false 27 | 28 | # # 29 | # Other 30 | # # 31 | 32 | [{*.nsh,*.yml,*.yaml,*.json}] 33 | indent_style = space 34 | indent_size = 2 35 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.js text eol=lf -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://buymeacoffee.com/aetherinox"] 2 | github: # [repo-name, aetherinox] 3 | patreon: # Replace with a single Patreon username 4 | open_collective: # name 5 | ko_fi: # Replace with a single Ko-fi username 6 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 7 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 8 | liberapay: # Replace with a single Liberapay username 9 | issuehunt: # Replace with a single IssueHunt username 10 | otechie: # Replace with a single Otechie username -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | # Pull Request 18 | Check which topic best describes your contribution: 19 | 20 | - [ ] Feature 21 | - [ ] Bug 22 | - [ ] Documentation / Wiki 23 | 24 | --- 25 | 26 | 27 |
28 | 29 | 30 | 31 | ### Description 32 | Explain here what your pull request includes and what you've done 33 | 34 | 35 | 36 |
37 | 38 | --- 39 | 40 |
41 | 42 | 43 | ### Before You Submit 44 | Please ensure you check the following items to indicate that you've read this section and completed each task 45 | 46 | - [ ] My code follows the [Contribution Guidelines](https://github.com/Aetherinox/obsidian-dataview-snippets/blob/main/CONTRIBUTING.md) 47 | - [ ] I give expressed consent for my work to be used in this repo 48 | - [ ] I have tested my work and it functions as intended 49 | - [ ] I have included documentation if the change requires such 50 | -------------------------------------------------------------------------------- /.github/changelog-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "title": "\n\n
\n\n#### 🪛 Continuous integration", 5 | "labels": [ "kind/ci", "ci" ] 6 | }, 7 | { 8 | "title": "\n\n
\n\n#### 🚀 Features", 9 | "labels": [ "kind/feature", "feature", "feat" ] 10 | }, 11 | { 12 | "title": "\n\n
\n\n#### 🐛 Bugfixes", 13 | "labels": [ "kind/bug", "fix", "bug" ] 14 | }, 15 | { 16 | "title": "\n\n
\n\n#### 🔧 Changes", 17 | "labels": [ "kind/chore", "change", "chore" ] 18 | }, 19 | { 20 | "title": "\n\n
\n\nn#### ✨ Optimizations", 21 | "labels": [ "kind/perf", "optimization", "perf", "optimize" ] 22 | }, 23 | { 24 | "title": "\n\n
\n\n#### 🚨 Security ", 25 | "labels": [ "kind/security", "security" ] 26 | }, 27 | { 28 | "title": "\n\n
\n\n#### 🧹 Housekeeping", 29 | "labels": [ "kind/refactor", "refactor", "style" ] 30 | }, 31 | { 32 | "title": "\n\n
\n\n#### 🐒 Miscellaneous", 33 | "labels": [ "kind/misc", "misc" ] 34 | }, 35 | { 36 | "title": "\n\n
\n\n#### ⛔ Deprecated", 37 | "labels": [ "kind/deprecate", "deprecate" ] 38 | }, 39 | { 40 | "title": "\n\n
\n\n#### ⛔ Removed", 41 | "labels": [ "kind/remove", "remove" ] 42 | }, 43 | { 44 | "title": "\n\n
\n\n#### 📦 Build & Dependencies", 45 | "labels": [ "kind/build", "build", "dependency", "dep", "package" ] 46 | }, 47 | { 48 | "title": "\n\n
\n\n#### ✏️ Docs", 49 | "labels": [ "kind/docs", "doc", "docs", "wiki" ] 50 | }, 51 | { 52 | "title": "\n\n
\n\n#### 🧪 Tests & Demo Vault", 53 | "labels": [ "kind/test", "test", "tests", "vault" ] 54 | } 55 | ], 56 | "sort": "ASC", 57 | "pr_template": "- ${{TITLE_ONLY}} : #{{MERGE_SHA}} @#{{AUTHOR}}", 58 | "empty_template": "- No major changes to address in this release", 59 | "custom_placeholders": [ 60 | { 61 | "name": "TITLE_ONLY", 62 | "source": "TITLE", 63 | "transformer": { 64 | "method": "regexr", 65 | "pattern": "(\\w+(\\(.+\\))?: ?)?(.+)", 66 | "target": "$2 $3" 67 | } 68 | } 69 | ], 70 | "label_extractor": [ 71 | { 72 | "pattern": "^(build|ci|change|chore|doc|docs|wiki|remove|deprecate|security|dependency|dep|package|feat|feature|fix|bug|perf|optimize|optimization|refactor|style|test|tests|vault):(.*)", 73 | "target": "$1", 74 | "on_property": "title" 75 | }, 76 | { 77 | "pattern": "^(build|ci|change|chore|doc|docs|wiki|remove|deprecate|security|dependency|dep|package|feat|feature|fix|bug|perf|optimize|optimization|refactor|style|test|tests|vault){1}(\\([\\w\\-\\.]+\\))?(!)?:(.*)", 78 | "target": "$1", 79 | "on_property": "title" 80 | } 81 | ], 82 | "duplicate_filter": { 83 | "pattern": "github.*", 84 | "on_property": "author", 85 | "method": "match" 86 | }, 87 | "max_tags_to_fetch": 200, 88 | "max_pull_requests": 200, 89 | "max_back_track_time_days": 365, 90 | "exclude_merge_branches": [], 91 | "tag_resolver": { 92 | "method": "semver" 93 | }, 94 | "base_branches": [] 95 | } 96 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2024 Aetherinox 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 | 23 | version: 2 24 | updates: 25 | - package-ecosystem: npm 26 | directory: "/" 27 | schedule: 28 | interval: daily 29 | labels: 30 | - "Type ◦ Dependency" 31 | 32 | - package-ecosystem: "github-actions" 33 | directory: "/" 34 | schedule: 35 | interval: "daily" 36 | labels: 37 | - "Type ◦ Git Action" -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # Number of labels to fetch (optional). Defaults to 100 2 | numLabels: 40 3 | # These labels will not be used even if the issue contains them (optional). 4 | # Pass a blank array if no labels are to be excluded. 5 | # excludeLabels: [] 6 | excludeLabels: 7 | - pinned 8 | # custom configuration to override default behaviour 9 | # control explicitly what gets added and when 10 | custom: 11 | - location: title 12 | keywords: 13 | - '[roadmap]' 14 | labels: 15 | - Type ◦ Roadmap 16 | - location: title 17 | keywords: 18 | - '[road-map]' 19 | labels: 20 | - Type ◦ Roadmap 21 | - location: title 22 | keywords: 23 | - '[bug]' 24 | labels: 25 | - Type ◦ Bug 26 | - location: title 27 | keywords: 28 | - '[issue]' 29 | labels: 30 | - Type ◦ Bug 31 | - location: title 32 | keywords: 33 | - '[feature]' 34 | labels: 35 | - Type ◦ Feature 36 | - location: body 37 | keywords: 38 | - 'request feature' 39 | labels: 40 | - Type ◦ Feature 41 | - location: title 42 | keywords: 43 | - '[request]' 44 | labels: 45 | - Type ◦ Feature -------------------------------------------------------------------------------- /.github/workflows/deploy-clean.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @author Aetherinox 4 | # @url https://github.com/Aetherinox 5 | # @usage cleans up the list of deployments in the environment history 6 | # edit the 'environment:' to determine which deployment to keep clean 7 | # - can be ran manually 8 | # 9 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 10 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 11 | # secrets.NPM_TOKEN self npmjs access token 12 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 13 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 14 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 15 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 16 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 17 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 18 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 19 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 20 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 21 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 22 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 23 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 24 | # 25 | # 26 | # @local these workflows can be tested locally through the use of `act` 27 | # https://github.com/nektos/act 28 | # Extract act to folder 29 | # Add system env var with path to act.exe 30 | # Run the commands: 31 | # git pull https://github.com/username/repo 32 | # act -W .github/workflows/deploy-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 33 | # act -W .github/workflows/deploy-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 34 | # # 35 | 36 | # # 37 | 38 | name: '🧹 Deployments › Clean' 39 | run-name: '🧹 Deployments › Clean' 40 | 41 | # # 42 | # triggers 43 | # # 44 | 45 | on: 46 | 47 | # # 48 | # Trigger > Workflow Dispatch 49 | # # 50 | 51 | workflow_dispatch: 52 | inputs: 53 | 54 | # # 55 | # Deployment Environment Name 56 | # 57 | # this is the name of the deployment item 58 | # # 59 | 60 | DEPLOYMENT_ENV: 61 | description: '📦 Deployment Environment' 62 | required: true 63 | default: 'orion' 64 | type: string 65 | 66 | # # 67 | # Delay 68 | # 69 | # Milliseconds to wait between cleaning up each action in history. Avoids secondary rate limit. Default: 500 70 | # # 71 | 72 | DEPLOYMENT_DELAY: 73 | description: '🕛 Delete Delay' 74 | required: true 75 | default: '1000' 76 | type: string 77 | 78 | # # 79 | # environment variables 80 | # # 81 | 82 | env: 83 | DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }} 84 | DEPLOYMENT_DELAY: ${{ github.event.inputs.DEPLOYMENT_DELAY || '1000' }} 85 | BOT_NAME_1: EuropaServ 86 | BOT_NAME_2: BinaryServ 87 | BOT_NAME_DEPENDABOT: dependabot[bot] 88 | BOT_NAME_RENOVATE: renovate[bot] 89 | 90 | # # 91 | # jobs 92 | # # 93 | 94 | jobs: 95 | cleanup: 96 | name: >- 97 | 🧹 Deployments › Clean 98 | runs-on: ubuntu-latest 99 | # runs-on: apollo-x64 100 | timeout-minutes: 5 101 | permissions: write-all 102 | 103 | steps: 104 | 105 | # # 106 | # Cleanup › Set Env Variables 107 | # # 108 | 109 | - name: >- 110 | 🕛 Get Timestamp 111 | id: task_cleanup_set_timestamp 112 | run: | 113 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 114 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 115 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 116 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 117 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 118 | 119 | # # 120 | # Release › Github › Checkout › Arm64 121 | # # 122 | 123 | - name: >- 124 | ✅ Checkout 125 | id: task_cleanup_gh_checkout 126 | uses: actions/checkout@v4 127 | with: 128 | fetch-depth: 0 129 | 130 | # # 131 | # Cleanup › Start 132 | # # 133 | 134 | - name: >- 135 | ⚙️ Deployments › Clean 136 | id: task_cleanup_start 137 | uses: Aetherinox/delete-deploy-env-action@v3 138 | with: 139 | token: ${{ secrets.SELF_TOKEN_CL }} 140 | environment: '${{ env.DEPLOYMENT_ENV }}' 141 | onlyRemoveDeployments: true 142 | delay: "${{ env.DEPLOYMENT_DELAY }}" 143 | 144 | # # 145 | # Cleanup › Get Weekly Commits 146 | # # 147 | 148 | - name: >- 149 | 🕛 Get Weekly Commit List 150 | id: task_cleanup_set_weekly_commit_list 151 | run: | 152 | echo 'WEEKLY_COMMITS<> $GITHUB_ENV 153 | git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV 154 | echo 'EOF' >> $GITHUB_ENV 155 | 156 | -------------------------------------------------------------------------------- /.github/workflows/history-clean.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @author Aetherinox 4 | # @url https://github.com/Aetherinox 5 | # @usage cleans all commit history for a repository 6 | # edit the 'environment:' to determine which deployment to keep clean 7 | # - can be ran manually 8 | # 9 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 10 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 11 | # secrets.NPM_TOKEN self npmjs access token 12 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 13 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 14 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 15 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 16 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 17 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 18 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 19 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 20 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 21 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 22 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 23 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 24 | # 25 | # 26 | # @local these workflows can be tested locally through the use of `act` 27 | # https://github.com/nektos/act 28 | # Extract act to folder 29 | # Add system env var with path to act.exe 30 | # Run the commands: 31 | # git pull https://github.com/username/repo 32 | # act -W .github/workflows/history-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 33 | # act -W .github/workflows/history-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 34 | # # 35 | 36 | name: '🧹 History › Clean' 37 | run-name: '🧹 History › Clean' 38 | 39 | # # 40 | # triggers 41 | # # 42 | 43 | on: 44 | 45 | # # 46 | # Trigger > Workflow Dispatch 47 | # # 48 | 49 | workflow_dispatch: 50 | inputs: 51 | 52 | # # 53 | # Commit Label 54 | # 55 | # the label to use when repository is cleaned 56 | # # 57 | 58 | COMMIT_LABEL: 59 | description: '🏷️ Commit Label' 60 | required: true 61 | default: 'cleanup' 62 | type: string 63 | 64 | # # 65 | # Main Branch 66 | # 67 | # main branch re-recreate 68 | # # 69 | 70 | BRANCH_MAIN: 71 | description: '🌳 Main Branch' 72 | required: true 73 | default: 'main' 74 | type: string 75 | 76 | # # 77 | # Deployment Environment Name 78 | # 79 | # this is the name of the deployment item 80 | # # 81 | 82 | DEPLOYMENT_ENV: 83 | description: '📦 Deployment Environment' 84 | required: true 85 | default: 'orion' 86 | type: string 87 | 88 | # # 89 | # environment variables 90 | # # 91 | 92 | env: 93 | COMMIT_LABEL: ${{ github.event.inputs.COMMIT_LABEL || 'cleanup' }} 94 | BRANCH_MAIN: ${{ github.event.inputs.BRANCH_MAIN || 'main' }} 95 | DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }} 96 | BOT_NAME_1: EuropaServ 97 | BOT_NAME_2: BinaryServ 98 | BOT_NAME_DEPENDABOT: dependabot[bot] 99 | BOT_NAME_RENOVATE: renovate[bot] 100 | 101 | # # 102 | # jobs 103 | # # 104 | 105 | jobs: 106 | history-clean: 107 | name: >- 108 | 🧹 History › Clean 109 | runs-on: ubuntu-latest 110 | # runs-on: apollo-x64 111 | timeout-minutes: 5 112 | steps: 113 | 114 | # # 115 | # History › Clean › Set TImestamps 116 | # # 117 | 118 | - name: >- 119 | 🕛 Get Timestamp 120 | id: task_history_clean_set_timestamp 121 | run: | 122 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 123 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 124 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 125 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 126 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 127 | 128 | # # 129 | # History › Clean › Checkout 130 | # # 131 | 132 | - name: >- 133 | ✅ Checkout 134 | id: task_history_clean_gh_checkout 135 | uses: actions/checkout@v4 136 | with: 137 | fetch-depth: 0 138 | 139 | # # 140 | # History › Clean › Git Identify 141 | # # 142 | 143 | - name: >- 144 | 🪪 Configure Git Identity 145 | id: task_history_clean_git_ident 146 | run: | 147 | git config --local user.email "github-actions[bot]@users.noreply.github.com" 148 | git config --local user.name "github-actions[bot]" 149 | 150 | # # 151 | # History › Clean › Pre-Commit 152 | # # 153 | 154 | - name: >- 155 | 📦 Commit › Pre-commit 156 | id: task_history_clean_commit_pre 157 | run: | 158 | now=$(date -u '+%m/%d/%Y %H:%M') 159 | commit_label="${{ env.COMMIT_LABEL }}" >> $GITHUB_ENV 160 | echo -e "$commit_label" 161 | commit_message="\\\`️️🧹 $commit_label 🧹\\\` \\\`$now UTC\\\`" >> $GITHUB_ENV 162 | echo -e "$commit_message" 163 | echo "COMMIT_MESSAGE=$(echo $commit_message)" >> $GITHUB_ENV 164 | echo "NOW=$(echo $now)" >> $GITHUB_ENV 165 | 166 | # # 167 | # History › Clean › Pre-Commit › Debug 168 | # # 169 | 170 | - name: >- 171 | 📦 Commit › Pre-commit › Debug 172 | id: task_history_clean_commit_debug 173 | run: | 174 | echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――" 175 | echo -e " Printing Values" 176 | echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――" 177 | echo -e " env.COMMIT_LABEL .................... ${{ env.COMMIT_LABEL }}" 178 | echo -e " env.COMMIT_MESSAGE .................. ${{ env.COMMIT_MESSAGE }}" 179 | echo -e " env.NOW ............................. ${{ env.NOW }}" 180 | 181 | # # 182 | # History › Clean › Start 183 | # # 184 | 185 | - name: >- 186 | 🧹 Clean Repo History 187 | id: task_history_clean_history 188 | run: | 189 | # Create a new orphan branch 190 | git checkout --orphan temp-branch 191 | 192 | # Add all files to the new branch 193 | git add -A 194 | 195 | # Commit the files to the new branch 196 | git commit -m "${{ env.COMMIT_MESSAGE }}" 197 | 198 | # Delete the old main branch 199 | git branch -D ${{ env.BRANCH_MAIN }} 200 | 201 | # Rename the new orphan branch to main 202 | git branch -m ${{ env.BRANCH_MAIN }} 203 | 204 | # Force push the new main branch to the remote repository 205 | git push -f origin ${{ env.BRANCH_MAIN }} 206 | 207 | # # 208 | # History › Clean › References 209 | # # 210 | 211 | - name: >- 212 | 🗑️ Clean References 213 | id: task_history_clean_references 214 | run: | 215 | # Remove remote-tracking references to deleted branches (optional) 216 | git fetch origin --prune 217 | 218 | git reflog expire --expire=now --all 219 | git gc --prune=now --aggressive 220 | 221 | # # 222 | # History › Clean › Commit 223 | # # 224 | 225 | - name: >- 226 | 📦 Commit › Execute 227 | id: task_history_clean_commit_execute 228 | uses: stefanzweifel/git-auto-commit-action@v5 229 | with: 230 | commit_message: ${{ env.COMMIT_MESSAGE }} 231 | -------------------------------------------------------------------------------- /.github/workflows/issues-accept.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @author Aetherinox 4 | # @url https://github.com/Aetherinox 5 | # @usage adds a label to a PR when the command "/accept" is typed in the issue comments 6 | # do not attempt to use env variables in if condition. 7 | # do not accept to change GITHUB_TOKEN. 8 | # 9 | # @notes requires the following labels to be created in your repo: 10 | # - bug 11 | # - feature 12 | # - urgent 13 | # - roadmap 14 | # 15 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 16 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 17 | # secrets.NPM_TOKEN self npmjs access token 18 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 19 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 20 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 21 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 22 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 23 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 24 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 25 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 26 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 27 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 28 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 29 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 30 | # 31 | # @local these workflows can be tested locally through the use of `act` 32 | # https://github.com/nektos/act 33 | # Extract act to folder 34 | # Add system env var with path to act.exe 35 | # Run the commands: 36 | # git pull https://github.com/username/repo 37 | # act -W .github/workflows/issues-accept.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 38 | # act -W .github/workflows/issues-accept.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 39 | # # 40 | 41 | name: '🎫 Issue › Accept' 42 | run-name: '🎫 Issue › Accept' 43 | 44 | # # 45 | # triggers 46 | # # 47 | 48 | on: 49 | issue_comment: 50 | types: [created] 51 | 52 | # # 53 | # environment variables 54 | # # 55 | 56 | env: 57 | LABEL_ACCEPT: 'Status › Accepted' 58 | DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }} 59 | BOT_NAME_1: EuropaServ 60 | BOT_NAME_2: BinaryServ 61 | BOT_NAME_DEPENDABOT: dependabot[bot] 62 | BOT_NAME_RENOVATE: renovate[bot] 63 | 64 | # # 65 | # jobs 66 | # # 67 | 68 | jobs: 69 | 70 | # # 71 | # Issues › Accept 72 | # # 73 | 74 | issues-accept: 75 | name: >- 76 | 🎫 Issue › Accept 77 | if: | 78 | contains(github.event.comment.body, '/accept') && github.event.comment.user.login == 'Aetherinox' 79 | runs-on: ubuntu-latest 80 | # runs-on: apollo-x64 81 | timeout-minutes: 5 82 | steps: 83 | 84 | # # 85 | # Issues › Accept › Set TImestamps 86 | # # 87 | 88 | - name: >- 89 | 🕛 Get Timestamp 90 | id: task_issues_accept_set_timestamp 91 | run: | 92 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 93 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 94 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 95 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 96 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 97 | 98 | # # 99 | # Issues › Accept › Add Label to accepted PR 100 | # # 101 | 102 | - name: >- 103 | 🏷️ Assign Label › ${{ env.LABEL_ACCEPT }} 104 | run: | 105 | gh issue edit "$NUMBER" --add-label "$LABELS" 106 | env: 107 | GITHUB_TOKEN: ${{ secrets.SELF_TOKEN_CL }} 108 | GH_REPO: ${{ github.repository }} 109 | NUMBER: ${{ github.event.issue.number }} 110 | LABELS: ${{ env.LABEL_ACCEPT }} 111 | 112 | # # 113 | # Issues › Accept › Add assignee to accepted PR 114 | # # 115 | 116 | - name: >- 117 | 🏷️ Assign Assignee › ${{ github.repository_owner }} 118 | run: | 119 | gh issue edit "$NUMBER" --add-assignee "$ASSIGNEE" 120 | env: 121 | GITHUB_TOKEN: ${{ secrets.SELF_TOKEN_CL }} 122 | GH_REPO: ${{ github.repository }} 123 | NUMBER: ${{ github.event.issue.number }} 124 | ASSIGNEE: ${{ github.repository_owner }} 125 | -------------------------------------------------------------------------------- /.github/workflows/labels-clean.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @desc manually activated workflow to remove issue labels 4 | # @author Aetherinox 5 | # @url https://github.com/Aetherinox 6 | # 7 | # @notes This Github action must be activated manually. This workflow script will do the following: 8 | # - Remove all existing labels in repository 9 | # 10 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 11 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 12 | # secrets.NPM_TOKEN self npmjs access token 13 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 14 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 15 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 16 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 17 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 18 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 19 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 20 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 21 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 22 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 23 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 24 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 25 | # 26 | # @local these workflows can be tested locally through the use of `act` 27 | # https://github.com/nektos/act 28 | # Extract act to folder 29 | # Add system env var with path to act.exe 30 | # Run the commands: 31 | # git pull https://github.com/username/repo 32 | # act -W .github/workflows/labels-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 33 | # act -W .github/workflows/labels-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 34 | # # 35 | 36 | name: '🧹 Labels › Clean' 37 | run-name: '🧹 Labels › Clean' 38 | 39 | # # 40 | # triggers 41 | # # 42 | 43 | on: 44 | workflow_dispatch: 45 | 46 | # # 47 | # environment variables 48 | # # 49 | 50 | env: 51 | ASSIGN_USER: Aetherinox 52 | BOT_NAME_1: EuropaServ 53 | BOT_NAME_2: BinaryServ 54 | BOT_NAME_DEPENDABOT: dependabot[bot] 55 | BOT_NAME_RENOVATE: renovate[bot] 56 | 57 | LABELS_JSON: | 58 | [ 59 | { "name": "bug", "color": "8F1784", "description": "Default github label" }, 60 | { "name": "documentation", "color": "8F1784", "description": "Default github label" }, 61 | { "name": "duplicate", "color": "8F1784", "description": "Default github label" }, 62 | { "name": "enhancement", "color": "8F1784", "description": "Default github label" }, 63 | { "name": "good first issue", "color": "8F1784", "description": "Default github label" }, 64 | { "name": "help wanted", "color": "8F1784", "description": "Default github label" }, 65 | { "name": "invalid", "color": "8F1784", "description": "Default github label" }, 66 | { "name": "question", "color": "8F1784", "description": "Default github label" }, 67 | { "name": "wontfix", "color": "8F1784", "description": "Default github label" }, 68 | { "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" }, 69 | { "name": "AC › Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" }, 70 | { "name": "AC › Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" }, 71 | { "name": "AC › Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" }, 72 | { "name": "AC › Passed", "color": "146b4a", "description": "Ready to be reviewed" }, 73 | { "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" }, 74 | { "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" }, 75 | { "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" }, 76 | { "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" }, 77 | { "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" }, 78 | { "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" }, 79 | { "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" }, 80 | { "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" }, 81 | { "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" }, 82 | { "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" }, 83 | { "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" }, 84 | { "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" }, 85 | { "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" }, 86 | { "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" }, 87 | { "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" }, 88 | { "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" }, 89 | { "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" }, 90 | { "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" }, 91 | { "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" }, 92 | { "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" }, 93 | { "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" }, 94 | { "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" }, 95 | { "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" }, 96 | { "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" }, 97 | { "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" }, 98 | { "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" }, 99 | { "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" }, 100 | { "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" }, 101 | { "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" }, 102 | { "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" }, 103 | { "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" }, 104 | { "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" }, 105 | { "name": "› Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" }, 106 | { "name": "› Design", "color": "FA70DE", "description": "Design related queries" }, 107 | { "name": "› Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" }, 108 | { "name": "› Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" }, 109 | { "name": "› Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" }, 110 | { "name": "› Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" }, 111 | { "name": "› Improvement", "color": "185c98", "description": "Enhance an existing feature" }, 112 | { "name": "› Performance", "color": "006b75", "description": "Web and desktop performance issues" }, 113 | { "name": "› Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" }, 114 | { "name": "› Security", "color": "F75D39", "description": "Security issues" }, 115 | { "name": "› Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" }, 116 | { "name": "› Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." }, 117 | { "name": "› Updater", "color": "1BADDE", "description": "Auto-updater issues" }, 118 | { "name": "› UX", "color": "1BADDE", "description": "UX and usability" }, 119 | { "name": "› Website", "color": "fef2c0", "description": "Website related issues" }, 120 | { "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" }, 121 | { "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" }, 122 | { "name": "📰 Progress Report", "color": "392297", "description": "Development updates" }, 123 | { "name": "📦 Release", "color": "277542", "description": "Release announcements" }, 124 | { "name": "✔️ Poll", "color": "972255", "description": "Community polls" }, 125 | { "name": "❔ Question", "color": "FFFFFF", "description": "All questions" } 126 | ] 127 | 128 | # # 129 | # jobs 130 | # # 131 | 132 | jobs: 133 | 134 | # # 135 | # Job › Remove Labels 136 | # 137 | # This job removes all existing labels 138 | # # 139 | 140 | issues-labels-clean: 141 | name: >- 142 | 🧹 Labels › Clean 143 | runs-on: ubuntu-latest 144 | # runs-on: apollo-x64 145 | timeout-minutes: 3 146 | permissions: 147 | contents: 'read' 148 | id-token: 'write' 149 | issues: 'write' 150 | steps: 151 | 152 | # # 153 | # Labels › Start 154 | # # 155 | 156 | - name: >- 157 | ✅ Start 158 | id: task_label_remove_start 159 | run: | 160 | echo "Starting workflow" 161 | 162 | # # 163 | # Labels › Set Env Variables 164 | # # 165 | 166 | - name: >- 167 | 🕛 Get Timestamp 168 | id: task_label_set_timestamp 169 | run: | 170 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 171 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 172 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 173 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 174 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 175 | 176 | # # 177 | # Labels › Checkout 178 | # # 179 | 180 | - name: >- 181 | ☑️ Checkout 182 | id: task_label_remove_checkout 183 | uses: actions/checkout@v4 184 | with: 185 | fetch-depth: 0 186 | 187 | # # 188 | # Labels › Start 189 | # # 190 | 191 | - name: >- 192 | 🏷️ Delete Existing Labels 193 | id: task_label_remove_run 194 | uses: actions/github-script@v7 195 | with: 196 | github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }} 197 | script: | 198 | const targetOwner = context.repo.owner; 199 | const targetRepo = context.repo.repo; 200 | 201 | // Fetch labels from the source repository 202 | const response = await github.rest.issues.listLabelsForRepo({ 203 | owner: targetOwner, 204 | repo: targetRepo, 205 | }); 206 | console.log("Labels fetched: ", response.data); 207 | 208 | const labels = response.data; 209 | if (labels.length === 0) { 210 | console.log("No labels found in the source repository."); 211 | } 212 | 213 | // Fetch all labels from the target repository and delete them 214 | const existingLabels = await github.rest.issues.listLabelsForRepo({ 215 | owner: targetOwner, 216 | repo: targetRepo, 217 | }); 218 | 219 | // const labels = JSON.parse( process.env.LABELS_JSON ); 220 | let result = Object.keys(labels).length; 221 | for ( const label of labels ) 222 | { 223 | try 224 | { 225 | await github.rest.issues.deleteLabel( 226 | { 227 | owner: context.repo.owner, 228 | repo: context.repo.repo, 229 | name: label.name, 230 | }); 231 | } 232 | catch ( err ) 233 | { 234 | console.error("Error: " + err); 235 | } 236 | } 237 | 238 | console.log("[Success]: Added " + result + " labels to repo"); 239 | 240 | return result 241 | 242 | # # 243 | # Labels › Get Weekly Commits 244 | # # 245 | 246 | - name: >- 247 | 🕛 Get Weekly Commit List 248 | id: task_label_set_weekly_commit_list 249 | run: | 250 | echo 'WEEKLY_COMMITS<> $GITHUB_ENV 251 | git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV 252 | echo 'EOF' >> $GITHUB_ENV 253 | -------------------------------------------------------------------------------- /.github/workflows/labels-create.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @author Aetherinox 4 | # @url https://github.com/Aetherinox 5 | # @usage manually activated workflow to create issue labels 6 | # 7 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 8 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 9 | # secrets.NPM_TOKEN self npmjs access token 10 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 11 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 12 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 13 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 14 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 15 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 16 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 17 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 18 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 19 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 20 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 21 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 22 | # 23 | # @local these workflows can be tested locally through the use of `act` 24 | # https://github.com/nektos/act 25 | # Extract act to folder 26 | # Add system env var with path to act.exe 27 | # Run the commands: 28 | # git pull https://github.com/username/repo 29 | # act -W .github/workflows/labels-create.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 30 | # act -W .github/workflows/labels-create.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 31 | # # 32 | 33 | name: '🎫 Labels › Create' 34 | run-name: '🎫 Labels › Create' 35 | 36 | # # 37 | # triggers 38 | # # 39 | 40 | on: 41 | workflow_dispatch: 42 | 43 | # # 44 | # environment variables 45 | # # 46 | 47 | env: 48 | ASSIGN_USER: Aetherinox 49 | BOT_NAME_1: EuropaServ 50 | BOT_NAME_2: BinaryServ 51 | BOT_NAME_DEPENDABOT: dependabot[bot] 52 | BOT_NAME_RENOVATE: renovate[bot] 53 | 54 | LABELS_JSON: | 55 | [ 56 | { "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" }, 57 | { "name": "AC › Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" }, 58 | { "name": "AC › Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" }, 59 | { "name": "AC › Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" }, 60 | { "name": "AC › Passed", "color": "146b4a", "description": "Ready to be reviewed" }, 61 | { "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" }, 62 | { "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" }, 63 | { "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" }, 64 | { "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" }, 65 | { "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" }, 66 | { "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" }, 67 | { "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" }, 68 | { "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" }, 69 | { "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" }, 70 | { "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" }, 71 | { "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" }, 72 | { "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" }, 73 | { "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" }, 74 | { "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" }, 75 | { "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" }, 76 | { "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" }, 77 | { "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" }, 78 | { "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" }, 79 | { "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" }, 80 | { "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" }, 81 | { "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" }, 82 | { "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" }, 83 | { "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" }, 84 | { "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" }, 85 | { "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" }, 86 | { "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" }, 87 | { "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" }, 88 | { "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" }, 89 | { "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" }, 90 | { "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" }, 91 | { "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" }, 92 | { "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" }, 93 | { "name": "› Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" }, 94 | { "name": "› Design", "color": "FA70DE", "description": "Design related queries" }, 95 | { "name": "› Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" }, 96 | { "name": "› Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" }, 97 | { "name": "› Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" }, 98 | { "name": "› Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" }, 99 | { "name": "› Improvement", "color": "185c98", "description": "Enhance an existing feature" }, 100 | { "name": "› Performance", "color": "006b75", "description": "Web and desktop performance issues" }, 101 | { "name": "› Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" }, 102 | { "name": "› Security", "color": "F75D39", "description": "Security issues" }, 103 | { "name": "› Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" }, 104 | { "name": "› Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." }, 105 | { "name": "› Updater", "color": "1BADDE", "description": "Auto-updater issues" }, 106 | { "name": "› UX", "color": "1BADDE", "description": "UX and usability" }, 107 | { "name": "› Website", "color": "fef2c0", "description": "Website related issues" }, 108 | { "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" }, 109 | { "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" }, 110 | { "name": "📰 Progress Report", "color": "392297", "description": "Development updates" }, 111 | { "name": "📦 Release", "color": "277542", "description": "Release announcements" }, 112 | { "name": "✔️ Poll", "color": "972255", "description": "Community polls" }, 113 | { "name": "❔ Question", "color": "FFFFFF", "description": "All questions" } 114 | ] 115 | 116 | # # 117 | # jobs 118 | # # 119 | 120 | jobs: 121 | 122 | # # 123 | # Job [ Verify / Create Labels ] 124 | # 125 | # This job will ensure you have labels already created in your repo. 126 | # All labels come from the JSON table LABELS_JSON. 127 | # # 128 | 129 | issues-labels-create: 130 | name: >- 131 | 🎫 Labels › Create 132 | runs-on: ubuntu-latest 133 | # runs-on: apollo-x64 134 | timeout-minutes: 3 135 | permissions: 136 | contents: 'read' 137 | id-token: 'write' 138 | issues: 'write' 139 | steps: 140 | 141 | # # 142 | # [ Create Labels ] Start 143 | # # 144 | 145 | - name: >- 146 | ✅ Start 147 | id: task_label_create_start 148 | run: | 149 | echo "Assigning labels and assignees" 150 | 151 | # # 152 | # Create Labels › Set Env Variables 153 | # # 154 | 155 | - name: >- 156 | 🕛 Get Timestamp 157 | id: task_label_set_timestamp 158 | run: | 159 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 160 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 161 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 162 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 163 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 164 | 165 | # # 166 | # [ Create Labels ] Checkout 167 | # # 168 | 169 | - name: >- 170 | ☑️ Checkout 171 | id: task_label_create_checkout 172 | uses: actions/checkout@v4 173 | with: 174 | fetch-depth: 0 175 | 176 | # # 177 | # [ Create Labels ] Verify Existing Labels 178 | # # 179 | 180 | - name: >- 181 | 🏷️ Verify Existing Labels 182 | id: task_label_verify_existing 183 | uses: actions/github-script@v7 184 | with: 185 | github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }} 186 | script: | 187 | const labels = JSON.parse( process.env.LABELS_JSON ); 188 | let result = Object.keys(labels).length; 189 | for ( const label of labels ) 190 | { 191 | try 192 | { 193 | await github.rest.issues.createLabel( 194 | { 195 | owner: context.repo.owner, 196 | repo: context.repo.repo, 197 | name: label.name, 198 | description: label.description || '', 199 | color: label.color 200 | }); 201 | } 202 | catch ( err ) 203 | { 204 | if ( err.status === 422 ) 205 | { 206 | console.log( `Label '${label.name}' already exists. Skipping.` ); 207 | } 208 | else 209 | { 210 | console.error( `Error creating label '${label.name}': ${err}` ); 211 | } 212 | } 213 | } 214 | 215 | console.log("[Success]: Added " + result + " labels to repo"); 216 | 217 | return result 218 | 219 | # # 220 | # Cleanup › Get Weekly Commits 221 | # # 222 | 223 | - name: >- 224 | 🕛 Get Weekly Commit List 225 | id: task_label_set_weekly_commit_list 226 | run: | 227 | echo 'WEEKLY_COMMITS<> $GITHUB_ENV 228 | git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV 229 | echo 'EOF' >> $GITHUB_ENV 230 | 231 | -------------------------------------------------------------------------------- /.github/workflows/ping-developer.yml: -------------------------------------------------------------------------------- 1 | # # 2 | # @type github workflow 3 | # @author Aetherinox 4 | # @url https://github.com/Aetherinox 5 | # @usage pings the developer when an issue comment is made 6 | # 7 | # @secrets secrets.SELF_TOKEN self github personal access token (fine-grained) 8 | # secrets.SELF_TOKEN_CL self github personal access token (classic) 9 | # secrets.NPM_TOKEN self npmjs access token 10 | # secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/ 11 | # secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/ 12 | # secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token 13 | # secrets.ORG_TOKEN org github personal access token (fine-grained) 14 | # secrets.ORG_TOKEN_CL org github personal access token (classic) 15 | # secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret 16 | # secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission 17 | # secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK 18 | # secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase 19 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord 20 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord 21 | # secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord 22 | # 23 | # @local these workflows can be tested locally through the use of `act` 24 | # https://github.com/nektos/act 25 | # Extract act to folder 26 | # Add system env var with path to act.exe 27 | # Run the commands: 28 | # git pull https://github.com/username/repo 29 | # act -W .github/workflows/ping-developer.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04 30 | # act -W .github/workflows/ping-developer.yml -s TOKEN_CL=XXXXXXXXXX --pull=false 31 | # # 32 | 33 | name: '💬 Ping › Developer' 34 | run-name: '💬 Ping › Developer' 35 | 36 | # # 37 | # triggers 38 | # # 39 | 40 | on: 41 | issue_comment: 42 | types: [created] 43 | 44 | # # 45 | # environment variables 46 | # # 47 | 48 | env: 49 | DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }} 50 | BOT_NAME_1: EuropaServ 51 | BOT_NAME_2: BinaryServ 52 | BOT_NAME_DEPENDABOT: dependabot[bot] 53 | BOT_NAME_RENOVATE: renovate[bot] 54 | 55 | # # 56 | # jobs 57 | # 58 | # env not available for job.if 59 | # # 60 | 61 | jobs: 62 | deploy: 63 | name: >- 64 | 💬 Issue › Accept 65 | runs-on: ubuntu-latest 66 | # runs-on: apollo-x64 67 | timeout-minutes: 5 68 | if: | 69 | contains(github.event.comment.body, '/ping') 70 | steps: 71 | 72 | # # 73 | # Ping › Developer › Set TImestamps 74 | # # 75 | 76 | - name: >- 77 | 🕛 Get Timestamp 78 | id: task_ping_developer_set_timestamp 79 | run: | 80 | echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV 81 | echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV 82 | echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV 83 | echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV 84 | echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV 85 | 86 | # # 87 | # Ping › Developer › Send Mail 88 | # 89 | # Add Label to accepted PR 90 | # 91 | # port 465 92 | # server_port: 465 93 | # secure: true 94 | # ignore_cert: false 95 | # 96 | # port 587 97 | # server_port: 587 98 | # secure: false 99 | # # 100 | 101 | - name: >- 102 | 📨 Send mail 103 | id: task_ping_developer_mail 104 | uses: dawidd6/action-send-mail@v5 105 | with: 106 | server_address: ${{ secrets.EMAIL_SMTP }} 107 | server_port: 465 108 | secure: true 109 | username: ${{ secrets.EMAIL_FROM }} 110 | password: ${{ secrets.EMAIL_KEY }} 111 | subject: "Github: Ping notification from ${{ github.repository }}" 112 | to: ${{ secrets.EMAIL_TO }} 113 | from: ${{ secrets.EMAIL_FROM }} 114 | html_body: | 115 | 116 | 117 | 118 | 119 | Title 120 | 121 | 140 | 141 | 142 | 143 |
144 |
145 |
146 | 147 |
148 |
149 | 150 |
151 |

[Github] Dear ${{github.repository_owner}},

152 |


You have received a ping notification from ${{ github.repository }} by ${{ github.event.comment.user.login }}.

153 |
154 |
155 |
156 | 157 | 158 | 159 | 161 | 162 | 163 | 164 | 166 | 167 | 168 | 169 | 171 | 172 | 173 | 174 | 176 | 177 | 178 | 179 | 181 | 182 | 183 | 184 |
Repository${{ github.repository }}
Date${{ env.NOW }}
Commenter${{ github.event.comment.user.login }}
Issue #${{ github.event.issue.number }}
ActionNotification
185 |
186 | 187 |

188 | 189 |
190 |
191 | 192 | 195 | 196 |
197 |
198 | 199 |

 

200 |


~ Github 201 |

202 |
203 | 204 |

205 | 206 |
207 | Copyright © ${{ env.YEAR }} 208 |
209 |
210 | 211 | 212 | ignore_cert: true 213 | convert_markdown: true 214 | priority: normal 215 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # # 2 | # Ignore everything 3 | # # 4 | 5 | /* 6 | 7 | # # 8 | # [WL]: Git Base Folders/Files 9 | # # 10 | 11 | !/.github 12 | !/.gitea 13 | !*README.md 14 | !*CHANGELOG.md 15 | !*CONTRIBUTE.md 16 | !*CONTRIBUTING.md 17 | 18 | # # 19 | # [WL]: Electron 20 | # # 21 | 22 | !/electron 23 | 24 | # # 25 | # [WL]: Test Folder 26 | # # 27 | 28 | !/Tests 29 | 30 | # # 31 | # [WL]: Manifest Folders 32 | # # 33 | 34 | !/Manifest 35 | 36 | # # 37 | # [WL]: Tools Folders 38 | # # 39 | 40 | !/Tools 41 | 42 | # # 43 | # [WL]: Dist 44 | # # 45 | 46 | !/dist 47 | 48 | # # 49 | # [WL]: assets 50 | # # 51 | 52 | !/assets 53 | 54 | # # 55 | # [WL]: Gitignore File 56 | # # 57 | 58 | !.gitignore 59 | 60 | # # 61 | # [WL]: Docs Folder 62 | # # 63 | 64 | !/docs 65 | 66 | # # 67 | # [WL]: Source Folder 68 | # # 69 | 70 | !/src 71 | 72 | # # 73 | # [WL]: Dist Folder 74 | # # 75 | 76 | !/dist 77 | 78 | # # 79 | # [WL]: Base Files 80 | # # 81 | 82 | !*.all-contributorsrc 83 | !*.editorconfig 84 | !*gistr.js 85 | !*manifest.json 86 | !*package.json 87 | !*package-lock.json 88 | !*rollup.config.js 89 | !*rollup.config.mjs 90 | !*tsconfig.json 91 | !*versions.json 92 | !sign.bat 93 | !*SHA*.asc 94 | !*SHA*.sig 95 | !*styles.css 96 | !*eslint.config.js 97 | !*.prettierignore 98 | !*.prettierrc 99 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .all-contributorsrc 2 | .github 3 | .gitea 4 | CONTRIBUTING 5 | CONTRIBUTING.md 6 | README 7 | README.md 8 | LICENSE 9 | node_modules 10 | coverage 11 | dist 12 | tests 13 | docs 14 | manifest.json 15 | tsconfig.json 16 | styles.css 17 | rollup.config.mjs 18 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | # 2 | # Try prettier's new ternary formatting before it becomes the 3 | # default behavior. 4 | # 5 | # only in prettier v3.x 6 | # 7 | # Moves the ? in multiline ternaries to the end of the first line 8 | # instead of the start of the second, along with several related 9 | # changes. 10 | # 11 | # @default : false 12 | # @ref : https://prettier.io/docs/en/options.html 13 | # https://prettier.io/docs/en/options.html#experimental-ternaries 14 | # https://github.com/prettier/prettier/pull/13183 15 | # # 16 | 17 | # experimentalTernaries: false 18 | 19 | # # 20 | # Specify the line length that the printer will wrap on. 21 | # 22 | # @default : 80 23 | # @ref : https://prettier.io/docs/en/options.html#print-width 24 | # # 25 | 26 | printWidth: 120 27 | 28 | # # 29 | # Specify the number of spaces per indentation-level. 30 | # 31 | # @default : 2 32 | # @ref : https://prettier.io/docs/en/options.html#tab-width 33 | # # 34 | 35 | tabWidth: 4 36 | 37 | # # 38 | # Indent lines with tabs instead of spaces. 39 | # 40 | # @default : false 41 | # @ref : https://prettier.io/docs/en/options.html#tabs 42 | # # 43 | 44 | useTabs: false 45 | 46 | # # 47 | # Print semicolons at the ends of statements. 48 | # 49 | # true : Add a semicolon at the end of every statement. 50 | # false : Only add semicolons at the beginning of lines that 51 | # may introduce ASI failures. 52 | # 53 | # @default : true 54 | # @ref : https://prettier.io/docs/en/options.html#semicolons 55 | # # 56 | 57 | semi: false 58 | 59 | # # 60 | # Use single quotes instead of double quotes. 61 | # 62 | # @default : false 63 | # @ref : https://prettier.io/docs/en/options.html#quotes 64 | # # 65 | 66 | singleQuote: true 67 | 68 | # # 69 | # Change when properties in objects are quoted. 70 | # 71 | # "as-needed" : Only add quotes around object properties where required. 72 | # "consistent" : If at least one property in an object requires quotes, quote all properties. 73 | # "preserve" : Respect the input use of quotes in object properties. 74 | # 75 | # 76 | # @default : "as-needed" 77 | # @ref : https://prettier.io/docs/en/options.html#quote-props 78 | # # 79 | 80 | quoteProps: 'preserve' 81 | 82 | # # 83 | # Use single quotes instead of double quotes in JSX. 84 | # 85 | # @default : false 86 | # @ref : https://prettier.io/docs/en/options.html#jsx-quotes 87 | # # 88 | 89 | jsxSingleQuote: true 90 | 91 | # # 92 | # Print trailing commas wherever possible in multi-line comma-separated 93 | # syntactic structures. 94 | # 95 | # (A single-line array, for example, never gets trailing commas.) 96 | # 97 | # Default value changed from es5 to all in v3.0.0 98 | # 99 | # "all" : Trailing commas wherever possible (including 100 | # function parameters and calls). To run, JavaScript 101 | # code formatted this way needs an engine that 102 | # supports ES2017 (Node.js 8+ or a modern browser) 103 | # or downlevel compilation. This also enables 104 | # trailing commas in type parameters in TypeScript 105 | # (supported since TypeScript 2.7 released in January 2018). 106 | # 107 | # "es5" : Trailing commas where valid in ES5 (objects, arrays, etc.). 108 | # 109 | # Trailing commas in type parameters in TypeScript and Flow. 110 | # "none" : No trailing commas. 111 | # 112 | # 113 | # @default : "all" 114 | # @ref : https://prettier.io/docs/en/options.html#trailing-commas 115 | # # 116 | 117 | trailingComma: none 118 | 119 | # # 120 | # Print spaces between brackets in object literals. 121 | # 122 | # true : Example: { foo: bar }. 123 | # false : Example: {foo: bar}. 124 | # 125 | # @default : true 126 | # @ref : https://prettier.io/docs/en/options.html#bracket-spacing 127 | # # 128 | 129 | bracketSpacing: true 130 | 131 | # # 132 | # Put the > of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the 133 | # last line instead of being alone on the next line (does not apply to self closing 134 | # elements). 135 | # 136 | # true : Example: 137 | # 138 | # 144 | # 145 | # false : Example: 146 | # 147 | # 154 | # 155 | # @default : false 156 | # @ref : https://prettier.io/docs/en/options.html#bracket-line 157 | # # 158 | 159 | bracketSameLine: false 160 | 161 | # # 162 | # Include parentheses around a sole arrow function parameter. 163 | # 164 | # First available in v1.9.0, default value changed from avoid to always in v2.0.0 165 | # 166 | # "always" : Always include parens. Example: (x) => x 167 | # "avoid" : Omit parens when possible. Example: x => x 168 | # 169 | # 170 | # @default : "always" 171 | # @ref : https://prettier.io/docs/en/options.html#arrow-function-parentheses 172 | # # 173 | 174 | arrowParens: always 175 | 176 | # # 177 | # By default, Prettier will not change wrapping in markdown text since some services 178 | # use a linebreak-sensitive renderer, e.g. GitHub comments and BitBucket. To have 179 | # Prettier wrap prose to the print width, change this option to "always". If you want 180 | # Prettier to force all prose blocks to be on a single line and rely on editor/viewer 181 | # soft wrapping instead, you can use "never". 182 | # 183 | # First available in v1.8.2 184 | # 185 | # "always" : Wrap prose if it exceeds the print width. 186 | # "never" : Un-wrap each block of prose into one line. 187 | # "preserve" : Do nothing, leave prose as-is. First available in v1.9.0 188 | # 189 | # 190 | # @default : "preserve" 191 | # @ref : https://prettier.io/docs/en/options.html#prose-wrap 192 | # # 193 | 194 | proseWrap: 'preserve' 195 | 196 | # # 197 | # Specify the global whitespace sensitivity for HTML, Vue, Angular, and Handlebars. 198 | # See whitespace-sensitive formatting for more info. 199 | # 200 | # First available in v1.15.0. First available for Handlebars in 2.3.0 201 | # 202 | # "css" : Respect the default value of CSS display property. 203 | # For Handlebars treated same as strict. 204 | # "strict" : Whitespace (or the lack of it) around all tags is considered significant. 205 | # "ignore" : Whitespace (or the lack of it) around all tags is considered insignificant. 206 | # 207 | # 208 | # @default : "css" 209 | # @ref : https://prettier.io/docs/en/options.html#html-whitespace-sensitivity 210 | # https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting 211 | # # 212 | 213 | htmlWhitespaceSensitivity: 'ignore' 214 | 215 | # # 216 | # For historical reasons, there exist two common flavors of line endings in text 217 | # files. That is: 218 | # - \n (or LF for Line Feed) 219 | # - \r\n (or CRLF for Carriage Return + Line Feed). 220 | # 221 | # The former is common on Linux and macOS, while the latter is prevalent on Windows. 222 | # Some details explaining why it is so can be found on Wikipedia. 223 | # 224 | # When people collaborate on a project from different operating systems, it becomes 225 | # easy to end up with mixed line endings in a shared git repository. It is also possible 226 | # for Windows users to accidentally change line endings in a previously committed file 227 | # from LF to CRLF. Doing so produces a large git diff and thus makes the line-by-line 228 | # history for a file (git blame) harder to explore. 229 | # 230 | # All modern text editors in all operating systems are able to correctly display line 231 | # endings when \n (LF) is used. However, old versions of Notepad for Windows will visually 232 | # squash such lines into one as they can only deal with \r\n (CRLF). 233 | # 234 | # First available in v1.15.0, default value changed from auto to lf in v2.0.0 235 | # 236 | # "lf" : Line Feed only (\n), common on Linux and macOS as well as inside git repos 237 | # "crlf" : Carriage Return + Line Feed characters (\r\n), common on Windows 238 | # "cr" : Carriage Return character only (\r), used very rarely 239 | # "auto" : Maintain existing line endings (mixed values within one file are normalised 240 | # by looking at what’s used after the first line) 241 | # 242 | # @default : "lf" 243 | # @ref : https://prettier.io/docs/en/options.html#end-of-line 244 | # # 245 | 246 | endOfLine: 'auto' 247 | 248 | # # 249 | # Control whether Prettier formats quoted code embedded in the file. 250 | # 251 | # When Prettier identifies cases where it looks like you've placed some code it knows 252 | # how to format within a string in another file, like in a tagged template in 253 | # JavaScript with a tag named html or in code blocks in Markdown, it will by default try 254 | # to format that code. 255 | # 256 | # Sometimes this behavior is undesirable, particularly in cases where you might not have 257 | # intended the string to be interpreted as code. This option allows you to switch between 258 | # the default behavior (auto) and disabling this feature entirely (off). 259 | # 260 | # First available in v2.1.0 261 | # 262 | # "auto" : Format embedded code if Prettier can automatically identify it. 263 | # "off" : Never automatically format embedded code. 264 | # 265 | # @default : "auto" 266 | # @ref : https://prettier.io/docs/en/options.html#embedded-language-formatting 267 | # # 268 | 269 | embeddedLanguageFormatting: 'auto' 270 | 271 | # # 272 | # Enforce single attribute per line in HTML, Vue and JSX. 273 | # 274 | # true : Enforce single attribute per line. 275 | # false : Do not enforce single attribute per line. 276 | # 277 | # @default : false 278 | # @ref : https://prettier.io/docs/en/options.html#single-attribute-per-line 279 | # # 280 | 281 | singleAttributePerLine: false 282 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 |
2 |
Thank you for your interest in contributing!
3 |

♾️ Contributing ♾️

4 | 5 |
6 | 7 | 8 | [![Version][github-version-img]][github-version-uri] 9 | [![Build Status][github-build-img]][github-build-uri] 10 | [![Downloads][github-downloads-img]][github-downloads-uri] 11 | [![Size][github-size-img]][github-size-img] 12 | [![Last Commit][github-commit-img]][github-commit-img] 13 | [![Contributors][contribs-all-img]](#contributors-) 14 | 15 | 16 |
17 | 18 |
19 | 20 | --- 21 | 22 |
23 | 24 | ## About 25 | 26 | Below are a list of ways that you can help contribute to this project, as well as policies and guides that explain how to get started. 27 | 28 | Please review everything on this page before you submit your contribution. 29 | 30 |
31 | 32 | --- 33 | 34 |
35 | 36 | - [About](#about) 37 | - [Issues, Bugs, Ideas](#issues-bugs-ideas) 38 | - [Contributing](#contributing) 39 | - [Before Submitting Pull Requests](#before-submitting-pull-requests) 40 | - [Conventional Commit Specification](#conventional-commit-specification) 41 | - [Types](#types) 42 | - [Example 1:](#example-1) 43 | - [Example 2:](#example-2) 44 | - [Commiting](#commiting) 45 | - [ESLint \& Prettier](#eslint--prettier) 46 | - [Packages](#packages) 47 | - [Configs](#configs) 48 | - [ESLint \>= v9 Config](#eslint--v9-config) 49 | - [ESLint \< v9 Config](#eslint--v9-config-1) 50 | - [Prettier](#prettier) 51 | - [Commenting](#commenting) 52 | - [Casing](#casing) 53 | - [Indentation Style](#indentation-style) 54 | - [Spaces Instead Of Tabs](#spaces-instead-of-tabs) 55 | 56 |
57 | 58 | --- 59 | 60 |
61 | 62 | ## Issues, Bugs, Ideas 63 | Stuff happens, and sometimes as best as we try, there may be issues within this project that we are unaware of. That is the great thing about open-source; anyone can use the program and contribute to making it better. 64 | 65 |
66 | 67 | If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/aetherinox/obsidian-dataview-snippets/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/aetherinox/obsidian-dataview-snippets/issues) and ensure nobody else has already submitted it. 68 | 69 |
70 | 71 | Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/aetherinox/obsidian-dataview-snippets/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as: 72 | - Bug report 73 | - Feature Suggestion 74 | 75 |
76 | 77 | When writing a new submission; ensure you fill out any of the questions asked of you. If you do not provide enough information, we cannot help. Be as detailed as possible, and provide any logs or screenshots you may have to help us better understand what you mean. Failure to fill out the submission properly may result in it being closed without a response. 78 | 79 |
80 | 81 | If you are submitting a bug report: 82 | 83 | - Explain the issue 84 | - Describe how you expect for a feature to work, and what you're seeing instead of what you expected. 85 | - List possible options for a resolution or insight 86 | - Provide screenshots, logs, or anything else that can visually help track down the issue. 87 | 88 |
89 | 90 |
91 | 92 | [![Submit Issue][btn-github-submit-img]][btn-github-submit-uri] 93 | 94 |
95 | 96 |
97 | 98 |
99 | 100 | **[`^ back to top ^`](#about)** 101 | 102 |
103 | 104 |
105 | 106 | --- 107 | 108 |
109 | 110 | ## Contributing 111 | If you are looking to contribute to this project by actually submit your own code; please review this section completely. There is important information and policies provided below that you must follow for your pull request to get accepted. 112 | 113 | The source is here for everyone to collectively share and colaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty. 114 | 115 | All contributions are made via pull requests. To create a pull request, you need a GitHub account. If you are unclear on this process, see [GitHub's documentation on forking and pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Pull requests should be targeted at the master branch. 116 | 117 |
118 | 119 | ### Before Submitting Pull Requests 120 | 121 | - Follow the repository's code formatting conventions (see below); 122 | - Include tests that prove that the change works as intended and does not add regressions; 123 | - Document the changes in the code and/or the project's documentation; 124 | - Your PR must pass the CI pipeline; 125 | - When submitting your Pull Request, use one of the following branches: 126 | - For bug fixes: `main` branch 127 | - For features & functionality: `development` branch 128 | - Include a proper git commit message following the [Conventional Commit Specification](https://www.conventionalcommits.org/en/v1.0.0/#specification). 129 | 130 |
131 | 132 | If you have completed the above tasks, the pull request is ready to be reviewed and your pull request's label will be changed to "Ready for Review". At this point, a human will need to step in and manually verify your submission. 133 | 134 | Reviewers will approve the pull request once they are satisfied with the patch it will be merged. 135 | 136 |
137 | 138 | ### Conventional Commit Specification 139 | 140 | When commiting your changes, we require you to follow the [Conventional Commit Specification](https://www.conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format: 141 | 142 |
143 | 144 | ``` 145 | [(optional )]: 146 | 147 | [optional ] 148 | 149 | [optional ] 150 | ``` 151 | 152 |
153 | 154 | #### Types 155 | | Type | Description | 156 | | --- | --- | 157 | | `feat` |
Introduce new feature

| 158 | | `fix` |
Bug fix

| 159 | | `deps` |
Add or update existing dependencies

| 160 | | `docs` |
Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator.

E.g: documentation, readme.md or markdown

| 161 | | `build` |
Changes to the build / compilation / packaging process or auxiliary tools such as doc generation

E.g: create new build tasks, update release script, etc.

| 162 | | `test` |
Add or refactor tests, no production code change. Changes the suite of automated tests for the app.

| 163 | | `perf` |
Performance improvement of algorithms or execution time of the app. Does not change an existing feature.

| 164 | | `style` |
Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code

E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc)

| 165 | | `refactor` |
Change to production code that leads to no behavior difference,

E.g: split files, rename variables, rename package, improve code style, etc.

| 166 | | `change` |
Change an existing feature.

| 167 | | `chore` |
Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintanence purposes.

E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file

| 168 | | `ci` |
Changes related to Continuous Integration (usually `yml` and other configuration files).

| 169 | | `misc` |
Anything that doesn't fit into another commit type. Usually doesn't change production code; yet is not ci, test or chore.

| 170 | | `revert` |
Revert a previous commit

| 171 | | `remove` |
Remove a feature from app. Features are usually first deprecated for a period of time before being removed. Removing a feature from the app may be considered a breaking change that will require a major version number increment.

| 172 | | `deprecate` |
Deprecate existing functionality, but does not remove it from the app.

| 173 | 174 |
175 | 176 | ##### Example 1: 177 | 178 | ``` 179 | feat(core): bug affecting menu [#22] 180 | ^───^────^ ^────────────────^ ^───^ 181 | | | | | 182 | | | | └───⫸ (ISSUE): Reference issue ID 183 | │ │ │ 184 | │ │ └───⫸ (DESC): Summary in present tense. Use lower case not title case! 185 | │ │ 186 | │ └───────────⫸ (SCOPE): The package(s) that this change affects 187 | │ 188 | └───────────────⫸ (TYPE): See list above 189 | ``` 190 | 191 |
192 | 193 | ##### Example 2: 194 | ``` 195 | (): [issue] 196 | | | | | 197 | | | | └─⫸ Reference issue id (optional) 198 | │ │ │ 199 | │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end. 200 | │ │ 201 | │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core| 202 | │ elements|forms|http|language-service|localize|platform-browser| 203 | │ platform-browser-dynamic|platform-server|router|service-worker| 204 | │ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve| 205 | │ devtools.... 206 | │ 207 | └─⫸ Commit Type: build|ci|doc|docs|feat|fix|perf|refactor|test 208 | website|chore|style|type|revert|deprecate 209 | ``` 210 | 211 |
212 | 213 | ### Commiting 214 | If you are pushing a commit which addresses a submitted issue, reference your issue at the end of the commit message. You may also optionally add the major issue to the end of your commit body. 215 | 216 | References should be on their own line, following the word `Ref` or `Refs` 217 | 218 | ``` 219 | Title: fix(core): fix error message displayed to users. [#22] 220 | Description: The description of your commit 221 | 222 | Ref: #22, #34, #37 223 | ``` 224 | 225 |
226 | 227 |
228 | 229 | ### ESLint & Prettier 230 | The following allows you to configure ESLint and Prettier. 231 | 232 |
233 | 234 | #### Packages 235 | We use the following packages for linting and prettier. 236 | 237 |
238 | 239 | | Package | Repo File | Description | 240 | | --- | --- | --- | 241 | | [typescript-eslint](https://npmjs.com/package/typescript-eslint) | [package.json](./package.json) | Tooling which enables you to use TypeScript with ESLint | 242 | | [eslint-plugin-prettier](https://npmjs.com/package/eslint-plugin-prettier) | [package.json](./package.json) | Runs Prettier as an ESLint rule and reports differences as individual ESLint issues. | 243 | | [@typescript-eslint/parser](https://npmjs.com/package/@typescript-eslint/parser) | [package.json](./package.json) | An ESLint parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code. | 244 | | [@typescript-eslint/eslint-plugin](https://npmjs.com/package/@typescript-eslint/eslint-plugin) | [package.json](./package.json) | An ESLint plugin which provides lint rules for TypeScript codebases. | 245 | | [@stylistic/eslint-plugin-js](https://npmjs.com/package/@stylistic/eslint-plugin-js) | [package.json](./package.json) | JavaScript stylistic rules for ESLint, migrated from eslint core. | 246 | | [@stylistic/eslint-plugin-ts](https://npmjs.com/package/@stylistic/eslint-plugin-ts) | [package.json](./package.json) | TypeScript stylistic rules for ESLint, migrated from typescript-eslint. | 247 | | [@stylistic/eslint-plugin-plus](https://npmjs.com/package/@stylistic/eslint-plugin-plus) | [package.json](./package.json) | Supplementary rules introduced by ESLint Stylistic. | 248 | | [prettier](https://npmjs.com/package/prettier) | [package.json](./package.json) | Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary. | 249 | 250 |
251 | 252 | You can add the following to your `package.json` file: 253 | ```yml 254 | "devDependencies": { 255 | "eslint-plugin-prettier": "^5.1.3", 256 | "typescript-eslint": "^7.14.0", 257 | "@typescript-eslint/parser": "^7.16.0", 258 | "@typescript-eslint/eslint-plugin": "^7.16.0", 259 | "@stylistic/eslint-plugin-js": "^2.3.0", 260 | "@stylistic/eslint-plugin-ts": "^2.3.0", 261 | "@stylistic/eslint-plugin-plus": "^2.3.0", 262 | "prettier": "^3.2.5" 263 | }, 264 | ``` 265 | 266 |
267 | 268 | #### Configs 269 | Within the root folder of the repo, there are several configuration files which you should be using within the project. These files dictate how prettier and eslint will behave and what is acceptable / not acceptable. 270 | 271 |
272 | 273 | Pick the config file below depending on which version of ESLint you are using. The v8 and older `.eslint` may not be there if we have migrated over to an Eslint v9 flat config file: 274 | 275 |
276 | 277 | ##### ESLint >= v9 Config 278 | - [eslint.config.mjs](https://github.com/aetherinox/obsidian-dataview-snippets/blob/main/eslint.config.mjs) 279 | - [eslint.config.js](https://github.com/aetherinox/obsidian-dataview-snippets/blob/main/eslint.config.js) 280 | 281 | https://github.com/Aetherinox/obsidian-dataview-snippets/blob/9e4aa53c1268d8852d3a0ab3980cb25adf239e99/eslint.config.js#L1-L151 282 | 283 |
284 | 285 | ##### ESLint < v9 Config 286 | - [.eslintrc](https://github.com/aetherinox/obsidian-dataview-snippets/blob/main/.eslintrc) 287 | 288 |
289 | 290 | ##### Prettier 291 | - [.prettierrc](https://github.com/aetherinox/obsidian-dataview-snippets/blob/main/.prettierrc) 292 | 293 | ```yml 294 | printWidth: 120, 295 | tabWidth: 4, 296 | useTabs: false, 297 | semi: false, 298 | singleQuote: true, 299 | quoteProps: 'preserve', 300 | jsxSingleQuote: true, 301 | trailingComma: 'none', 302 | bracketSpacing: true, 303 | bracketSameLine: false, 304 | arrowParens: 'always', 305 | proseWrap: 'preserve', 306 | htmlWhitespaceSensitivity: 'ignore', 307 | endOfLine: 'auto', 308 | embeddedLanguageFormatting: 'auto', 309 | singleAttributePerLine: false, 310 | experimentalTernaries: false 311 | ``` 312 | 313 |
314 | 315 | When submitting your pull request, these linting and style rules will be verified with all of your files. If you did not follow these rules; the linter tests on your pull request will fail; and you'll be expected to correct these issues before your submission will be transferred over for human review. 316 | 317 |
318 | 319 | ### Commenting 320 | 321 | Comment your code. If someone else comes along, they should be able to do a quick glance and have an idea of what is going on. Plus it helps novice readers to better understand the process. 322 | 323 | You may use block style commenting, or single lines: 324 | 325 | ```javascript 326 | /* 327 | make platform writable 328 | */ 329 | 330 | Object.defineProperty(process, 'platform', { 331 | value: platform, 332 | writable: true 333 | }); 334 | 335 | afterEach(() => { 336 | process.platform = platform; 337 | process.env.OSTYPE = OSTYPE; 338 | }); 339 | 340 | /* 341 | tests to decide if the end-user is running on Darwin or another platform. 342 | */ 343 | 344 | test(`Return true if platform is Darwin`, () => { 345 | process.platform = 'darwin'; 346 | expect(bIsDarwin()).toBe(true); 347 | }); 348 | 349 | test(`Return false if platform is not Darwin`, () => { 350 | process.platform = 'linux'; 351 | expect(bIsDarwin()).toBe(false); 352 | }); 353 | ``` 354 | 355 |
356 | 357 | ### Casing 358 | 359 | When writing your code, ensure you stick to `camelCase` 360 | 361 | ```javascript 362 | let myVar = 'one'; 363 | let secondVar = 'two'; 364 | ``` 365 | 366 |
367 | 368 | ### Indentation Style 369 | For files that are not controlled by prettier or eslint; you should be using the `Allman Style`. This style puts the brace associated with a control statement on the next line, indented. Statements within the braces are indented to the same level as the braces. 370 | 371 |
372 | 373 | ```javascript 374 | return { 375 | status: "failure", 376 | user: 377 | { 378 | id: "1aaa35aa-fb3a-62ae-ffec-a14g7fc401ac", 379 | label: "Test String", 380 | } 381 | }; 382 | ``` 383 | 384 |
385 | 386 | ### Spaces Instead Of Tabs 387 | When writing your code, set your IDE to utilize **spaces**, with a configured size of `4 characters`. If this project utilizes ESLint, you should find the file `.editorconfig` in the root directory of the repo which defines how the file should be formatted. Load that file into programs such as Visual Studio Code. 388 | 389 |
390 | 391 |
392 | 393 |
394 | 395 | **[`^ back to top ^`](#about)** 396 | 397 |
398 | 399 |
400 |
401 | 402 | 403 | 404 | 405 | 406 | [general-npmjs-uri]: https://npmjs.com 407 | [general-nodejs-uri]: https://nodejs.org 408 | [general-npmtrends-uri]: http://npmtrends.com/obsidian-dataview-snippets 409 | 410 | 411 | [github-version-img]: https://img.shields.io/github/v/tag/Aetherinox/obsidian-dataview-snippets?logo=GitHub&label=Version&color=ba5225 412 | [github-version-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 413 | 414 | 415 | [npm-version-img]: https://img.shields.io/npm/v/obsidian-dataview-snippets?logo=npm&label=Version&color=ba5225 416 | [npm-version-uri]: https://npmjs.com/package/obsidian-dataview-snippets 417 | 418 | 419 | [pypi-version-img]: https://img.shields.io/pypi/v/obsidian-dataview-snippets-plugin 420 | [pypi-version-uri]: https://pypi.org/project/obsidian-dataview-snippets-plugin/ 421 | 422 | 423 | [license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0 424 | [license-mit-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/blob/main/LICENSE 425 | 426 | 427 | [github-downloads-img]: https://img.shields.io/github/downloads/Aetherinox/obsidian-dataview-snippets/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892 428 | [github-downloads-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 429 | 430 | 431 | [npmjs-downloads-img]: https://img.shields.io/npm/dw/%40aetherinox%2Fmkdocs-link-embeds?logo=npm&&label=Downloads&color=376892 432 | [npmjs-downloads-uri]: https://npmjs.com/package/obsidian-dataview-snippets 433 | 434 | 435 | [github-size-img]: https://img.shields.io/github/repo-size/Aetherinox/obsidian-dataview-snippets?logo=github&label=Size&color=59702a 436 | [github-size-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 437 | 438 | 439 | [npmjs-size-img]: https://img.shields.io/npm/unpacked-size/obsidian-dataview-snippets/latest?logo=npm&label=Size&color=59702a 440 | [npmjs-size-uri]: https://npmjs.com/package/obsidian-dataview-snippets 441 | 442 | 443 | [codecov-coverage-img]: https://img.shields.io/codecov/c/github/Aetherinox/obsidian-dataview-snippets?token=MPAVASGIOG&logo=codecov&logoColor=FFFFFF&label=Coverage&color=354b9e 444 | [codecov-coverage-uri]: https://codecov.io/github/Aetherinox/obsidian-dataview-snippets 445 | 446 | 447 | [contribs-all-img]: https://img.shields.io/github/all-contributors/Aetherinox/obsidian-dataview-snippets?logo=contributorcovenant&color=de1f6f&label=contributors 448 | [contribs-all-uri]: https://github.com/all-contributors/all-contributors 449 | 450 | 451 | [github-build-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30 452 | [github-build-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/release.yml 453 | 454 | 455 | [github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30 456 | [github-build-pypi-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/pypi-release.yml 457 | 458 | 459 | [github-tests-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/npm-tests.yml?logo=github&label=Tests&color=2c6488 460 | [github-tests-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/npm-tests.yml 461 | 462 | 463 | [github-commit-img]: https://img.shields.io/github/last-commit/Aetherinox/obsidian-dataview-snippets?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131 464 | [github-commit-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/commits/main/ 465 | 466 | 467 | [btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF 468 | [btn-github-submit-uri]: https://github.com/aetherinox/obsidian-dataview-snippets/issues 469 | 470 | 471 | 472 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Aetherinox 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
Dataview Snippets
3 |

⭕ Obsidian Snippet Collection ⭕

4 | 5 |
6 | 7 |

A collection of dataview scripts which can be utilized within your Obsidian.md notes to perform various tasks and display data.

8 | 9 |
10 |
11 | 12 |
13 | 14 |
15 | 16 | 17 | [![Version][github-version-img]][github-version-uri] 18 | [![Build Status][github-build-img]][github-build-uri] 19 | [![Downloads][github-downloads-img]][github-downloads-uri] 20 | [![Size][github-size-img]][github-size-img] 21 | [![Last Commit][github-commit-img]][github-commit-img] 22 | [![Contributors][contribs-all-img]](#contributors-) 23 | 24 | 25 |
26 | 27 |
28 | 29 | --- 30 | 31 |
32 | 33 | - [About](#about) 34 | - [Snippets](#snippets) 35 | - [Table of Contents: Version 1](#table-of-contents-version-1) 36 | - [Table of Contents: Version 2](#table-of-contents-version-2) 37 | - [Subfolder Data](#subfolder-data) 38 | - [Bad Links: Version 1](#bad-links-version-1) 39 | - [Tag Cloud: Version 1](#tag-cloud-version-1) 40 | - [Tag Cloud: Version 2](#tag-cloud-version-2) 41 | - [Page Cloud: Version 1](#page-cloud-version-1) 42 | - [Alphabetized List: Version 1](#alphabetized-list-version-1) 43 | - [Contributors ✨](#contributors-) 44 | 45 |
46 | 47 | --- 48 | 49 |
50 | 51 | ## About 52 | This repo originally started a single **Table of Contents** script which displays at the top of your obsidian note. However, numerous other scripts have been added since then. 53 | 54 | The snippets in this repo require you to download and install the following: 55 | - [Obsidian.md](obsidian.md/) 56 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 57 | 58 |
59 | 60 | --- 61 | 62 |
63 | 64 | ## Snippets 65 | The following snippets are available in this repo 66 | 67 |
68 | 69 | ### Table of Contents: Version 1 70 | 71 |

72 | 73 | The `Table of Contents: Version 1` snippet displays a table of contents. It compiles a list of all your folder's current subpages and pulls the headers from each page to display in a simple and neat list. 74 | 75 |
76 | 77 | For this version, you will need to create a new **Folder Note** using the [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes), and then paste the provided code at the top of the new folder note. 78 | 79 |
80 | 81 | This version requires you to install the following: 82 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 83 | - [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) 84 | 85 |
86 | 87 |
88 | 89 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/TOC%20Version%201) 90 | 91 |
92 | 93 |

94 | 95 | --- 96 | 97 |

98 | 99 | ### Table of Contents: Version 2 100 | 101 |

102 | 103 | The `Table of Contents: Version 2` snippet displays a table of contents. It compiles a list of all your folder's current subpages and pulls the headers from each page to display in a simple and neat list. 104 | 105 |
106 | 107 | To use this snippet, paste the provided table of contents code at the top of a regular Obsidian note. It will fetch all of the headers which exist on that same page and display them in an unordered list at the top. 108 | 109 |
110 | 111 | This version requires you to install the following: 112 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 113 | 114 |
115 | 116 |
117 | 118 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/TOC%20Version%202) 119 | 120 |
121 | 122 |

123 | 124 | --- 125 | 126 |

127 | 128 | ### Subfolder Data 129 | 130 |

131 | 132 | The `Subfolder Data` snippet displays a table of contents listing based on a specified subfolder. This is useful if you want to pull a list of headers which exist on a page that is not associated to the current folder you are working in. 133 | 134 | The other snippets above also support subpages, but this one is a bit more customized for subfolder management. 135 | 136 |
137 | 138 | This version **requires** you to install the following: 139 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 140 | 141 | The following plugins are **optional**: 142 | - [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) 143 | 144 |
145 | 146 |
147 | 148 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Subfolder%20Data) 149 | 150 |
151 | 152 |

153 | 154 | --- 155 | 156 |

157 | 158 | ### Bad Links: Version 1 159 | 160 |

161 | 162 | The `Bad Links: Version 1` snippet displays a list of internal links within your vault that lead nowhere (are broken). 163 | 164 | To fix these, you can delete the link on the associated page, or you can click each item in the list and create a new page. Once the link has been fixed, it will be removed from the list. 165 | 166 |
167 | 168 | This version **requires** you to install the following: 169 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 170 | 171 |
172 | 173 |
174 | 175 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Bad%20Links%201) 176 | 177 |
178 | 179 |

180 | 181 | --- 182 | 183 |

184 | 185 | ### Tag Cloud: Version 1 186 | 187 |

188 | 189 | The `Tag Cloud: Version 1` snippet fetches a list of tags associated to your vault and displays them in a series of columns. 190 | 191 | Each tag can be clicked on, which will open the Search interface and display all other pages associated to the selected tag. 192 | 193 | The functionality of `Version 1` and `Version 2` are the same. Both just have difference appearances. 194 | 195 | 196 |
197 | 198 | This version **requires** you to install the following: 199 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 200 | 201 |
202 | 203 |
204 | 205 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Tag%20Cloud%201) 206 | 207 |
208 | 209 |

210 | 211 | --- 212 | 213 |

214 | 215 | ### Tag Cloud: Version 2 216 | 217 |

218 | 219 | The `Tag Cloud: Version 2` snippet fetches a list of tags associated to your vault and displays them in a series of columns. 220 | 221 | Each tag can be clicked on, which will open the Search interface and display all other pages associated to the selected tag. 222 | 223 | The functionality of `Version 1` and `Version 2` are the same. Both just have difference appearances. 224 | 225 |
226 | 227 | This version **requires** you to install the following: 228 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 229 | 230 |
231 | 232 |
233 | 234 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Tag%20Cloud%202) 235 | 236 |
237 | 238 |

239 | 240 | --- 241 | 242 |

243 | 244 | ### Page Cloud: Version 1 245 | 246 |

247 | 248 | The `Page Cloud: Version 1` snippet fetches a list of pages within your vault and displays them in a cloud structure. 249 | 250 | Each page can be clicked on which will re-direct you to that particular page. Page titles also support the frontmatter values: 251 | - name 252 | - title 253 | - alias 254 | 255 | The functionality of `Version 1` and `Version 2` are the same. Both just have difference appearances. 256 | 257 |
258 | 259 | This version **requires** you to install the following: 260 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 261 | 262 |
263 | 264 |
265 | 266 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Page%20Cloud%201) 267 | 268 |
269 | 270 |

271 | 272 | --- 273 | 274 |

275 | 276 | ### Alphabetized List: Version 1 277 | 278 |

279 | 280 | The `Alphabetized List: Version 1` snippet fetches a list of pages within your vault and displays them in a alphabetized list. 281 | 282 | Each page can be clicked on which will re-direct you to that particular page. Page titles also support the frontmatter values: 283 | - name 284 | - title 285 | - alias 286 | 287 |
288 | 289 | This version **requires** you to install the following: 290 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 291 | 292 |
293 | 294 |
295 | 296 | [![View](https://img.shields.io/badge/%20-%20View%20Readme-%20%23de2343?style=for-the-badge&logo=github&logoColor=FFFFFF)](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Alphabetized%20List%201) 297 | 298 |
299 | 300 |
301 | 302 | --- 303 | 304 |
305 | 306 | ## Contributors ✨ 307 | We are always looking for contributors. If you feel that you can provide something useful to Gistr, then we'd love to review your suggestion. Before submitting your contribution, please review the following resources: 308 | 309 | - [Pull Request Procedure](.github/PULL_REQUEST_TEMPLATE.md) 310 | - [Contributor Policy](CONTRIBUTING.md) 311 | 312 |
313 | 314 | Want to help but can't write code? 315 | - Review [active questions by our community](https://github.com/Aetherinox/obsidian-dataview-snippets/labels/help%20wanted) and answer the ones you know. 316 | 317 |
318 | 319 | The following people have helped get this project going: 320 | 321 |
322 | 323 |
324 | 325 | 326 | [![Contributors][contribs-all-img]](#contributors-) 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 |
Aetherinox
Aetherinox

💻 📆 🔍
339 |
340 | 341 | 342 | 343 | 344 |
345 |
346 | 347 | 348 | 349 | 350 | 351 | [general-npmjs-uri]: https://npmjs.com 352 | [general-nodejs-uri]: https://nodejs.org 353 | [general-npmtrends-uri]: http://npmtrends.com/obsidian-dataview-snippets 354 | 355 | 356 | [github-version-img]: https://img.shields.io/github/v/tag/Aetherinox/obsidian-dataview-snippets?logo=GitHub&label=Version&color=ba5225 357 | [github-version-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 358 | 359 | 360 | [npm-version-img]: https://img.shields.io/npm/v/obsidian-dataview-snippets?logo=npm&label=Version&color=ba5225 361 | [npm-version-uri]: https://npmjs.com/package/obsidian-dataview-snippets 362 | 363 | 364 | [pypi-version-img]: https://img.shields.io/pypi/v/obsidian-dataview-snippets-plugin 365 | [pypi-version-uri]: https://pypi.org/project/obsidian-dataview-snippets-plugin/ 366 | 367 | 368 | [license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0 369 | [license-mit-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/blob/main/LICENSE 370 | 371 | 372 | [github-downloads-img]: https://img.shields.io/github/downloads/Aetherinox/obsidian-dataview-snippets/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892 373 | [github-downloads-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 374 | 375 | 376 | [npmjs-downloads-img]: https://img.shields.io/npm/dw/%40aetherinox%2Fmkdocs-link-embeds?logo=npm&&label=Downloads&color=376892 377 | [npmjs-downloads-uri]: https://npmjs.com/package/obsidian-dataview-snippets 378 | 379 | 380 | [github-size-img]: https://img.shields.io/github/repo-size/Aetherinox/obsidian-dataview-snippets?logo=github&label=Size&color=59702a 381 | [github-size-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/releases 382 | 383 | 384 | [npmjs-size-img]: https://img.shields.io/npm/unpacked-size/obsidian-dataview-snippets/latest?logo=npm&label=Size&color=59702a 385 | [npmjs-size-uri]: https://npmjs.com/package/obsidian-dataview-snippets 386 | 387 | 388 | [codecov-coverage-img]: https://img.shields.io/codecov/c/github/Aetherinox/obsidian-dataview-snippets?token=MPAVASGIOG&logo=codecov&logoColor=FFFFFF&label=Coverage&color=354b9e 389 | [codecov-coverage-uri]: https://codecov.io/github/Aetherinox/obsidian-dataview-snippets 390 | 391 | 392 | [contribs-all-img]: https://img.shields.io/github/all-contributors/Aetherinox/obsidian-dataview-snippets?logo=contributorcovenant&color=de1f6f&label=contributors 393 | [contribs-all-uri]: https://github.com/all-contributors/all-contributors 394 | 395 | 396 | [github-build-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30 397 | [github-build-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/release.yml 398 | 399 | 400 | [github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30 401 | [github-build-pypi-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/pypi-release.yml 402 | 403 | 404 | [github-tests-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/obsidian-dataview-snippets/npm-tests.yml?logo=github&label=Tests&color=2c6488 405 | [github-tests-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/actions/workflows/npm-tests.yml 406 | 407 | 408 | [github-commit-img]: https://img.shields.io/github/last-commit/Aetherinox/obsidian-dataview-snippets?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131 409 | [github-commit-uri]: https://github.com/Aetherinox/obsidian-dataview-snippets/commits/main/ 410 | 411 | 412 | 413 | -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/example_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/example_2.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/example_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/example_3.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/example_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/example_4.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/example_5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/example_5.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Alphabetized List 1/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Alphabetized List 1/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Alphabetized List 2/code.txt: -------------------------------------------------------------------------------- 1 | dv.container.className += ' atx-alv1-dataview' 2 | 3 | var html = ""; 4 | let arrAlphabet = []; 5 | let arrPages = dv.pages( "" ) 6 | .forEach( p => 7 | { 8 | const file = p.file 9 | const file_path = file.path; 10 | const file_name = file.name; 11 | const file_label = file.frontmatter.name || file.frontmatter.title || file.frontmatter.alias || file_name; 12 | 13 | const letter = file_label.charAt( 0 ).toUpperCase( ); 14 | let index = arrAlphabet.findIndex( ( item ) => item.name === letter ); 15 | 16 | if ( index === -1 ) 17 | arrAlphabet.push( { name: letter, pages: [ { name: file_name, label: file_label, path: file_path } ] } ); 18 | else 19 | { 20 | var item = arrAlphabet.find( item => item.name == letter ); 21 | let arr = item.pages; 22 | 23 | arr.push( { name: file_name, label: file_label, path: file_path } ); 24 | } 25 | 26 | arrAlphabet.sort( ( a, b ) => a.name.localeCompare( b.name ) ) 27 | }); 28 | 29 | const ulAlphabet = dv.el( 'ul', '', { container: dv.container } ); 30 | 31 | dv.list( 32 | dv.array( arrAlphabet ) 33 | .forEach( obj => 34 | { 35 | const arrPages = obj.pages; 36 | const liAlphabet = dv.el( 'li', obj.name, { container: ulAlphabet } ); 37 | const ulPages = dv.el( 'ul', '', { container: liAlphabet }); 38 | 39 | Promise.all( arrPages.map( async ( pages ) => 40 | { 41 | const page_path = pages.path; 42 | const page_name = pages.name; 43 | const page_label = pages.label; 44 | 45 | const file_link = dv.fileLink( page_path, false, page_label ); 46 | 47 | dv.el( 'li', file_link, { container: ulPages } ); 48 | 49 | } 50 | )); 51 | }) 52 | ) 53 | 54 | const divClose = dv.el( 'div', html, { container: dv.container, cls: 'atx-alv1-close' } ); -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/example_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/example_1.png -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/example_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/example_2.gif -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/example_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/example_3.gif -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/example_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/example_4.gif -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/example_5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/example_5.gif -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Bad Links 1/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Bad Links 1/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Page Cloud 1/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Page Cloud 1/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/Page Cloud 1/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Page Cloud 1/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Page Cloud 1/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Page Cloud 1/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Page Cloud 1/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Page Cloud 1/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Page Cloud 1/images/install_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Page Cloud 1/images/install_4.gif -------------------------------------------------------------------------------- /Snippets/Subfolder Data/README.md: -------------------------------------------------------------------------------- 1 | # Obsidian: Subfolder Data 2 | This snippet requires a copy of [Obsidian.md](obsidian.md/) 3 |
4 | This snippet requires the [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview). 5 | 6 |

7 | 8 | ## About 9 | The `Subfolder Data` snippet displays a table of contents listing based on a specified subfolder. This is useful if you want to pull a list of headers which exist on a page that is not associated to the current folder you are working in. 10 | 11 |
12 | 13 | At the time of writing this script, I am using the following: 14 | 15 | | Software | Version | 16 | | --- | --- | 17 | | [Obsidian.md](https://obsidian.md/) | ![GitHub release](https://img.shields.io/github/v/release/obsidianmd/obsidian-releases?label=v&color=ba0f56) | 18 | | [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) | ![GitHub release](https://img.shields.io/github/v/release/blacksmithgu/obsidian-dataview?label=v&color=ba0f56) | 19 | | [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) | ![GitHub release](https://img.shields.io/github/v/release/LostPaul/obsidian-folder-notes?label=v&color=ba0f56) | 20 | 21 |
22 | 23 | ### Previews 24 | The following are preview images of what the snippet will do and appear like: 25 | 26 |
27 | 28 |

29 | 30 |
31 | 32 |

33 | 34 | --- 35 | 36 |

37 | 38 | ## Usage 39 | 40 | - Install [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 41 | - Install [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) *(if wanting to use notes*) 42 | - Copy the code below and paste it in a note. 43 | 44 |
45 | 46 | ````shell 47 | ```dataviewjs 48 | /* 49 | Table of Contents Script > Version 3 50 | 51 | This version allows for pulling subfolder notes to 52 | another table of contents page. 53 | 54 | Excludes any subfolder table of contents pages 55 | labeled FOLDERNAME/FOLDERNAME.md 56 | 57 | Change "General" to the subpage you are wanting to target 58 | */ 59 | 60 | const path_sub = "General" 61 | 62 | let count = 0; 63 | const path_base = dv.current().file.path 64 | const path_targ = path_base.substr(0, path_base.lastIndexOf("/")); 65 | const path_fnote_excl = path_sub + ".md" 66 | const filter_page = '"' + path_targ + "/" + path_sub + '"'; 67 | const filter_folder = path_targ + "/" + path_sub; 68 | 69 | let p = dv.pages(filter_page) 70 | .where(p => p.file.name != dv.current().file.name) // Filter out the current page 71 | .where(p => p.file.folder == filter_folder) // Filter out folders 72 | .where(p => !p.file.path.endsWith(path_fnote_excl) ) // Filter folder note index 73 | .sort(p => p.file.path) 74 | .forEach(p => 75 | { 76 | dv.header(4, p.file.name); // display page name as header 77 | const cache = this.app.metadataCache.getCache(p.file.path); 78 | 79 | if (cache) 80 | { 81 | const headings = cache.headings; // get headings from cache 82 | 83 | if (headings) 84 | { 85 | const houtput = headings.slice(1) // exclude the first heading 86 | .filter(h => h.level <= 6) 87 | .map(h => 88 | { 89 | var file_head = h.heading 90 | var header_skip = file_head.replace(/ /g,"_").toLowerCase(); 91 | if (header_skip === "table_of_contents" || header_skip === "toc") 92 | { 93 | return "" 94 | } 95 | 96 | count++; 97 | 98 | // Determine indentation based on heading level 99 | let indent = " ".repeat(h.level); 100 | var file_name = p.file.name; 101 | 102 | // remove backticks and tag symbols 103 | var file_head = file_head.replace(/`/g, ''); 104 | var file_head = file_head.replace(/#/g, ''); 105 | var file_title = h.heading.split('#')[0]; 106 | 107 | let objLink = "[[" + file_name + "#" + file_head + "|" + file_title + "]]"; 108 | 109 | if ( h.level == 1 ) 110 | return indent + "- " + objLink + ""; 111 | else if ( h.level == 2 ) 112 | return indent + " - " + objLink + ""; 113 | else if ( h.level == 3 ) 114 | return indent + " - " + objLink + ""; 115 | else if ( h.level == 4 ) 116 | return indent + " - " + objLink + ""; 117 | else if ( h.level == 5 ) 118 | return indent + " - " + objLink + ""; 119 | else if ( h.level == 6 ) 120 | return indent + " - " + objLink + ""; 121 | else 122 | return indent + "- " + objLink; 123 | }) 124 | .join("\n") 125 | 126 | dv.el("div", houtput); 127 | dv.el("div", "
"); 128 | } 129 | } 130 | }); 131 | 132 | /* 133 | display NO RESULTS 134 | */ 135 | 136 | if (count === 0) 137 | { 138 | const rootNode = dv.el("div", "No results", { cls: "toc_results_none" }); 139 | rootNode.setAttribute("style", "text-align:center;"); 140 | } 141 | ``` 142 | ```` 143 | 144 |
145 | 146 | Ensure you change the path to the **subfolder** you want to target: 147 | 148 | ```javascript 149 | const path_sub = "General" 150 | ``` 151 | 152 |
153 | 154 | In the screenshot example, I changed it `Plugins` because the Plugins folder is a subfolder of what I wanted to target and build a table of contents from. You can use an entirely different path to whatever folder you want to generate a list of headers from. 155 | 156 | ```javascript 157 | const path_sub = "Plugins" 158 | ``` 159 | 160 |
161 | 162 | Next, you need to add some custom CSS. 163 | Open Obsidian Settings, click **Appearance**, and then scroll all the way down. (See image below). 164 | 165 | Click the mini folder icon to open your **Obsidian Snippets folder**. 166 | 167 |
168 | 169 |

170 | 171 |
172 | 173 | Create a new file named whatever (`toc.css` in our example). 174 | 175 | Copy the code below and paste it into the new `toc.css` file which should be in `YourVaultName/.obsidian/snippets/toc.css` 176 | 177 |
178 | 179 |

180 | 181 |
182 | 183 | ```css 184 | /* 185 | Snippet: Table of Contents 186 | */ 187 | 188 | /* 189 | toc > header 2 190 | */ 191 | 192 | .toc_h2 a 193 | { 194 | color: #7fa8f5 !important; 195 | font-size: 10pt; 196 | font-weight: lighter; 197 | line-height: 20px; 198 | } 199 | 200 | /* 201 | toc > header 3 202 | */ 203 | 204 | .toc_h3 a 205 | { 206 | color: #f85289 !important; 207 | font-size: 9pt; 208 | font-weight: lighter; 209 | line-height: 20px; 210 | } 211 | 212 | /* 213 | toc > header 4, 5, 6 214 | */ 215 | 216 | .toc_h4 a, .toc_h5 a, .toc_h6 a 217 | { 218 | color: #969696 !important; 219 | font-size: 8pt; 220 | font-weight: normal; 221 | line-height: 20px; 222 | } 223 | 224 | /* 225 | toc > bad links > path 226 | */ 227 | 228 | .toc_badpaths_path, .toc_badpaths_path a 229 | { 230 | color: #adadad !important; 231 | font-size: 8pt; 232 | font-weight: normal; 233 | line-height: 20px; 234 | } 235 | 236 | /* 237 | toc > no results 238 | */ 239 | 240 | .toc_results_none 241 | { 242 | text-align: center; 243 | font-size: 12pt; 244 | } 245 | ``` 246 | 247 |
248 | 249 | Save the file and go back to **Obsidian Settings** -> **Appearance**. Scroll all the way down and enable the checkbox to the right of `toc.css`. 250 | 251 |

252 | 253 |
254 | 255 | You should see a table of contents which is populated with the headings of your subfolders. -------------------------------------------------------------------------------- /Snippets/Subfolder Data/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Subfolder Data/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/Subfolder Data/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Subfolder Data/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Subfolder Data/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Subfolder Data/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Subfolder Data/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Subfolder Data/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Subfolder Data/snippet-version3: -------------------------------------------------------------------------------- 1 | ```dataviewjs 2 | /* 3 | Table of Contents Script > Version 3 4 | 5 | This version allows for pulling subfolder notes to 6 | another table of contents page. 7 | 8 | Excludes any subfolder table of contents pages 9 | labeled FOLDERNAME/FOLDERNAME.md 10 | 11 | change "General" to the subpage you are wanting to target 12 | */ 13 | 14 | const path_sub = "General" 15 | 16 | let count = 0; 17 | const path_base = dv.current().file.path 18 | const path_targ = path_base.substr(0, path_base.lastIndexOf("/")); 19 | const path_fnote_excl = path_sub + ".md" 20 | const filter_page = '"' + path_targ + "/" + path_sub + '"'; 21 | const filter_folder = path_targ + "/" + path_sub; 22 | 23 | let p = dv.pages(filter_page) 24 | .where(p => p.file.name != dv.current().file.name) // Filter out the current page 25 | .where(p => p.file.folder == filter_folder) // Filter out folders 26 | .where(p => !p.file.path.endsWith(path_fnote_excl) ) // Filter folder note index 27 | .sort(p => p.file.path) 28 | .forEach(p => 29 | { 30 | dv.header(4, p.file.name); // display page name as header 31 | const cache = this.app.metadataCache.getCache(p.file.path); 32 | 33 | if (cache) 34 | { 35 | const headings = cache.headings; // get headings from cache 36 | 37 | if (headings) 38 | { 39 | const houtput = headings.slice(1) // exclude the first heading 40 | .filter(h => h.level <= 6) 41 | .map(h => 42 | { 43 | count++; 44 | 45 | // Determine indentation based on heading level 46 | let indent = " ".repeat(h.level); 47 | var file_name = p.file.name; 48 | 49 | // remove backticks and tag symbols 50 | var file_head = h.heading 51 | var file_head = file_head.replace(/`/g, ''); 52 | var file_head = file_head.replace(/#/g, ''); 53 | var file_title = h.heading.split('#')[0]; 54 | 55 | let objLink = "[[" + file_name + "#" + file_head + "|" + file_title + "]]"; 56 | 57 | if ( h.level == 1 ) 58 | return indent + "- " + objLink + ""; 59 | else if ( h.level == 2 ) 60 | return indent + " - " + objLink + ""; 61 | else if ( h.level == 3 ) 62 | return indent + " - " + objLink + ""; 63 | else if ( h.level == 4 ) 64 | return indent + " - " + objLink + ""; 65 | else if ( h.level == 5 ) 66 | return indent + " - " + objLink + ""; 67 | else if ( h.level == 6 ) 68 | return indent + " - " + objLink + ""; 69 | else 70 | return indent + "- " + objLink; 71 | }) 72 | .join("\n") 73 | 74 | dv.el("div", houtput); 75 | dv.el("div", "
"); 76 | } 77 | } 78 | }); 79 | 80 | /* 81 | display NO RESULTS 82 | */ 83 | 84 | if (count === 0) 85 | { 86 | const rootNode = dv.el("div", "No results", { cls: "toc-results-none" }); 87 | rootNode.setAttribute("style", "text-align:center;"); 88 | } 89 | ``` -------------------------------------------------------------------------------- /Snippets/TOC Version 1/README.md: -------------------------------------------------------------------------------- 1 |
2 |

📃 Table of Contents: Version 1 📃

3 |
4 |

A dataview script which displays a table of contents. It compiles a list of all your folder's current subpages and pulls the headers from each page to display in a simple and neat list.

5 | 6 |
7 | 8 |
9 | 10 | > [!NOTE] 11 | > Need a table of contents snippet which does **not** require the [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes)? 12 | > 13 | > Click here to install [Table of Contents: Version 2](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/TOC%20Version%202) 14 | 15 |
16 | 17 | ## About 18 | 19 | This snippet requires you to have: 20 | - [Obsidian.md](obsidian.md/) 21 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 22 | - [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) 23 | 24 |
25 | 26 | The code for this version should be pasted inside a **Folder Note**. It will fetch all of the files that exist inside that folder. 27 | 28 |
29 | 30 | At the time of writing this script, I am using the following: 31 | 32 | | Software | Version | 33 | | --- | --- | 34 | | [Obsidian.md](https://obsidian.md/) | ![GitHub release](https://img.shields.io/github/v/release/obsidianmd/obsidian-releases?label=v&color=ba0f56) | 35 | | [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) | ![GitHub release](https://img.shields.io/github/v/release/blacksmithgu/obsidian-dataview?label=v&color=ba0f56) | 36 | | [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) | ![GitHub release](https://img.shields.io/github/v/release/LostPaul/obsidian-folder-notes?label=v&color=ba0f56) | 37 | 38 |
39 | 40 | ### Previews 41 | The following are preview images of what the snippet will do and appear like: 42 | 43 |
44 | 45 |

46 | 47 |
48 | 49 |

50 | 51 | --- 52 | 53 |

54 | 55 | ## Usage 56 | 57 | - Install [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 58 | - Install [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes) 59 | - Right-click on a folder, select `Folder Note Commands` and select `Create Folder Note` 60 | - Copy the code below and paste in Obsidian folder note: 61 | 62 |
63 | 64 | ````javascript 65 | ```dataviewjs 66 | 67 | /* 68 | Table of Contents Script > Version 1 69 | 70 | This version requires the plugins: 71 | https://github.com/LostPaul/obsidian-folder-notes 72 | https://github.com/blacksmithgu/obsidian-dataview 73 | 74 | Create a new folder, right-click, and create folder note. 75 | Click inside the folder note and paste the code below. 76 | 77 | Inside that folder, place the files you want the table of 78 | contents to display. Make sure each file contains headers. 79 | */ 80 | 81 | let count = 0; 82 | const path_base = dv.current().file.path 83 | const path_targ = path_base.substr(0, path_base.lastIndexOf("/")); 84 | const path_sub = "" 85 | 86 | const filter_page = '"' + path_targ + "" + path_sub + '"'; 87 | const filter_folder = path_targ + path_sub; 88 | 89 | let p = dv.pages(filter_page) 90 | .where(p => p.file.name != dv.current().file.name) // Filter out the current page 91 | .where(p => p.file.folder == filter_folder) // Filter out folders 92 | .sort(p => p.file.path) 93 | .forEach(p => 94 | { 95 | dv.header(4, p.file.name); // display page name as header 96 | const cache = this.app.metadataCache.getCache(p.file.path); 97 | 98 | if (cache) 99 | { 100 | const headings = cache.headings; // get headings from cache 101 | 102 | if ( typeof headings === 'undefined') { 103 | dv.el("div", '⭕ No Subheaders Found', { cls: "toc_results_none_subheader" }); 104 | dv.el("div", "
"); 105 | return; 106 | } 107 | 108 | if (headings) 109 | { 110 | const houtput = headings.slice(0) // exclude the first heading 111 | .filter(h => h.level <= 6) 112 | .map(h => 113 | { 114 | let file_head = h.heading 115 | const header_skip = file_head.replace(/ /g,"_").toLowerCase(); 116 | if (header_skip === "table_of_contents" || header_skip === "toc") 117 | { 118 | return "" 119 | } 120 | 121 | count++; 122 | 123 | // Determine indentation based on heading level 124 | let indent = " ".repeat(h.level); 125 | const file_name = p.file.name; 126 | 127 | // remove backticks and tag symbols 128 | file_head = file_head.replace(/`/g, ''); 129 | file_head = file_head.replace(/#/g, ''); 130 | const file_title = h.heading.split('#')[0]; 131 | 132 | let objLink = "[[" + file_name + "#" + file_head + "|" + file_title + "]]"; 133 | 134 | if ( h.level == 1 ) 135 | return indent + "- " + objLink + ""; 136 | else if ( h.level == 2 ) 137 | return indent + " - " + objLink + ""; 138 | else if ( h.level == 3 ) 139 | return indent + " - " + objLink + ""; 140 | else if ( h.level == 4 ) 141 | return indent + " - " + objLink + ""; 142 | else if ( h.level == 5 ) 143 | return indent + " - " + objLink + ""; 144 | else if ( h.level == 6 ) 145 | return indent + " - " + objLink + ""; 146 | else 147 | return 'No Result' 148 | }) 149 | .join("\n") 150 | 151 | dv.el("div", houtput); 152 | dv.el("div", "
"); 153 | } 154 | } 155 | }); 156 | 157 | /* 158 | display NO RESULTS 159 | */ 160 | 161 | if (count === 0) 162 | { 163 | const rootNode = dv.el("div", "No results", { cls: "toc_results_none" }); 164 | rootNode.setAttribute("style", "text-align:center;"); 165 | } 166 | ``` 167 | ```` 168 | 169 |
170 | 171 | If you want to target a subfolder / path, you can modify the variable `path_sub`. If you leave it blank, it will target the folder you paste the code in. 172 | 173 | ```javascript 174 | const path_sub = "Path/To/Subfolder" 175 | ``` 176 | 177 |
178 | 179 | Next, you need to add some custom CSS. 180 | Open Obsidian Settings, click **Appearance**, and then scroll all the way down. (See image below). 181 | 182 | Click the mini folder icon to open your **Obsidian Snippets folder**. 183 | 184 |
185 | 186 |

187 | 188 |
189 | 190 | Create a new file named whatever (`toc.css` in our example). 191 | 192 | Copy the code below and paste it into the new `toc.css` file which should be in `YourVaultName/.obsidian/snippets/toc.css` 193 | 194 |
195 | 196 |

197 | 198 |
199 | 200 | ```css 201 | /* 202 | Snippet: Table of Contents 203 | */ 204 | 205 | /* 206 | header 2 207 | */ 208 | 209 | .toc_h2 a 210 | { 211 | color: #7fa8f5 !important; 212 | font-size: 10pt; 213 | font-weight: lighter; 214 | line-height: 20px; 215 | } 216 | 217 | /* 218 | header 3 219 | */ 220 | 221 | .toc_h3 a 222 | { 223 | color: #f85289 !important; 224 | font-size: 9pt; 225 | font-weight: lighter; 226 | line-height: 20px; 227 | } 228 | 229 | /* 230 | header 4, 5, 6 231 | */ 232 | 233 | .toc_h4 a, .toc_h5 a, .toc_h6 a 234 | { 235 | color: #969696 !important; 236 | font-size: 8pt; 237 | font-weight: normal; 238 | line-height: 20px; 239 | } 240 | 241 | /* 242 | bad links > path 243 | */ 244 | 245 | .toc_badpaths_path, .toc_badpaths_path a 246 | { 247 | color: #adadad !important; 248 | font-size: 8pt; 249 | font-weight: normal; 250 | line-height: 20px; 251 | } 252 | 253 | /* 254 | no results > total 255 | */ 256 | 257 | .toc_results_none 258 | { 259 | text-align: center; 260 | font-size: 12pt; 261 | } 262 | 263 | /* 264 | no results > subheader 265 | */ 266 | 267 | .toc_results_none_subheader 268 | { 269 | padding-left: 12px; 270 | font-size: 10pt; 271 | } 272 | ``` 273 | 274 |
275 | 276 | Save the file and go back to **Obsidian Settings** -> **Appearance**. Scroll all the way down and enable the checkbox to the right of `toc.css`. 277 | 278 |

279 | 280 |
281 | 282 | You should see a table of contents which is populated with the headings of your subfolders. 283 | 284 |

285 | 286 | --- 287 | 288 |

289 | 290 | ## Customization 291 | ### How to make page title above the each list appear bigger 292 | In your code, locate 293 | ```javascript 294 | dv.header(4, p.file.name); 295 | ``` 296 | 297 | The `4` stands for `H4` or header 4. To make the text bigger, change that number to `3 or lower`. Overall, it accepts any number between `1 - 6`, with 1 being the biggest and 6 being the smallest text size. 298 | 299 |
300 |
301 | 302 | ### Make each page title not display as a listed item 303 | Locate the code toward the top: 304 | ```javascript 305 | dv.header(4, p.file.name); 306 | ``` 307 | and replace it with: 308 | ```javascript 309 | dv.el("div", p.file.name); 310 | ``` 311 | 312 | This will force each page title to display in a `div` and not as header object. 313 | 314 |
315 |
316 | 317 | ### My list is cutting off the first header of each page 318 | Locate the following code: 319 | ```javascript 320 | const houtput = headings.slice(1) 321 | ``` 322 | 323 | The number `1` represents how many headers on the page that should be excluded from the first going from the top down. If you enter the number `0`, then no headers will be filtered out / all will show in the list. If you enter `3`, then the first three headers of each page will not appear in the table of contents list. 324 | 325 | To disable any headers from being excluded in the list, change the code above to the following: 326 | ```javascript 327 | const houtput = headings.slice(0) 328 | ``` 329 | 330 |
331 |
332 | 333 | ### Exclude certain headers from appearing in the list 334 | Much like the example above which allows you to filter from from the top, you can also filter exactly which headers display in the list with the following code: 335 | ```javascript 336 | .filter(h => h.level <= 6) 337 | ``` 338 | 339 | The number `6` represents which headers will be included in the list. If you change the value to a `4`, that means any sections of your page with headers 5 or 6 will not show. 340 | ``` 341 | ##### This is H5 342 | ###### This is H6 343 | ``` 344 | 345 |
346 |
347 | 348 | ### Making the gap between each list smaller/bigger 349 | You need to modify the following: 350 | ```javascript 351 | dv.el("div", "

"); 352 | ``` 353 | Each `
` is a line break. The more breaks you add, the larger the gap between each list. Remove each break to make the gap smaller. 354 | 355 |
356 |
-------------------------------------------------------------------------------- /Snippets/TOC Version 1/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 1/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/TOC Version 1/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 1/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/TOC Version 1/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 1/images/install_2.png -------------------------------------------------------------------------------- /Snippets/TOC Version 1/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 1/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/TOC Version 2/README.md: -------------------------------------------------------------------------------- 1 |
2 |

📃 Table of Contents: Version 2 📃

3 |
4 |

A dataview script which displays a table of contents. The code within this page should be pasted at the top of your Obsidian note which contains headers and subheaders. It will populate a list of all the headers and show them in a list.

5 | 6 |
7 | 8 |
9 | 10 | > [!NOTE] 11 | > Want a table of contents which is compatible with the [Folder Notes Plugin](https://github.com/LostPaul/obsidian-folder-notes)? 12 | > 13 | > Click here to install [Table of Contents: Version 1](https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/TOC%20Version%201) 14 | 15 |
16 | 17 | ## About 18 | 19 | This snippet requires you to have: 20 | - [Obsidian.md](obsidian.md/) 21 | - [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 22 | 23 |
24 | 25 | The code for this version should be pasted at the top of a note. It will fetch all of the headers that exist on that page and display them in an unordered list at the top. 26 | 27 |
28 | 29 | At the time of writing this script, I am using the following: 30 | 31 | | Software | Version | 32 | | --- | --- | 33 | | [Obsidian.md](https://obsidian.md/) | ![GitHub release](https://img.shields.io/github/v/release/obsidianmd/obsidian-releases?label=v&color=ba0f56) | 34 | | [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) | ![GitHub release](https://img.shields.io/github/v/release/blacksmithgu/obsidian-dataview?label=v&color=ba0f56) | 35 | 36 |
37 | 38 | ### Previews 39 | The following are preview images of what the snippet will do and appear like: 40 | 41 |
42 | 43 |

44 | 45 |
46 | 47 |

48 | 49 | --- 50 | 51 |

52 | 53 | ## Usage 54 | 55 | - Install [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 56 | - Copy the code below and paste it at the top of a note you want to display a list of headers for: 57 | 58 |
59 | 60 | ````javascript 61 | ```dataviewjs 62 | 63 | /* 64 | Table of Contents Script > Version 2 65 | 66 | Should be pasted at the top of the page to outline 67 | all of the headers you want to list on the same page 68 | 69 | For this script, "path_sub" should not be edited. 70 | */ 71 | 72 | let count = 0; 73 | const path_base = dv.current().file.path 74 | const path_targ = path_base.substr(0, path_base.lastIndexOf(".md")); 75 | const path_sub = "" 76 | 77 | const filter_page = '"' + path_targ + "" + path_sub + '"'; 78 | const filter_folder = path_targ + path_sub; 79 | 80 | let p = dv.pages(filter_page) 81 | .sort(p => p.file.path) 82 | .forEach(p => 83 | { 84 | // dv.header(4, p.file.name); // display page name as header 85 | const cache = this.app.metadataCache.getCache(p.file.path); 86 | 87 | if (cache) 88 | { 89 | const headings = cache.headings; // get headings from cache 90 | 91 | if (headings) 92 | { 93 | const houtput = headings.slice(0) // exclude the first heading 94 | .filter(h => h.level <= 6) 95 | .map(h => 96 | { 97 | let file_head = h.heading 98 | const header_skip = file_head.replace(/ /g,"_").toLowerCase(); 99 | if (header_skip === "table_of_contents" || header_skip === "toc") 100 | { 101 | return "" 102 | } 103 | 104 | count++; 105 | 106 | // Determine indentation based on heading level 107 | let indent = " ".repeat(h.level); 108 | const file_name = p.file.name; 109 | 110 | // remove backticks and tag symbols 111 | file_head = file_head.replace(/`/g, ''); 112 | file_head = file_head.replace(/#/g, ''); 113 | const file_title = h.heading.split('#')[0]; 114 | 115 | let objLink = "[[" + file_name + "#" + file_head + "|" + file_title + "]]"; 116 | 117 | if ( h.level == 1 ) 118 | return indent + "- " + objLink + ""; 119 | else if ( h.level == 2 ) 120 | return indent + " - " + objLink + ""; 121 | else if ( h.level == 3 ) 122 | return indent + " - " + objLink + ""; 123 | else if ( h.level == 4 ) 124 | return indent + " - " + objLink + ""; 125 | else if ( h.level == 5 ) 126 | return indent + " - " + objLink + ""; 127 | else if ( h.level == 6 ) 128 | return indent + " - " + objLink + ""; 129 | else 130 | return indent + "- " + objLink; 131 | }) 132 | .join("\n") 133 | 134 | dv.el("div", houtput); 135 | dv.el("div", "
"); 136 | } 137 | } 138 | }); 139 | 140 | /* 141 | display NO RESULTS 142 | */ 143 | 144 | if (count === 0) 145 | { 146 | const rootNode = dv.el("div", "No results", { cls: "toc_results_none" }); 147 | rootNode.setAttribute("style", "text-align:center;"); 148 | } 149 | ``` 150 | ```` 151 | 152 |
153 | 154 | If you want to target a subfolder / path, you can modify the variable `path_sub`. If you leave it blank, it will target the folder you paste the code in. 155 | 156 | ```javascript 157 | const path_sub = "Path/To/Subfolder" 158 | ``` 159 | 160 |
161 | 162 | Next, you need to add some custom CSS. 163 | Open Obsidian Settings, click **Appearance**, and then scroll all the way down. (See image below). 164 | 165 | Click the mini folder icon to open your **Obsidian Snippets folder**. 166 | 167 |
168 | 169 |

170 | 171 |
172 | 173 | Create a new file named whatever (`toc.css` in our example). 174 | 175 | Copy the code below and paste it into the new `toc.css` file which should be in `YourVaultName/.obsidian/snippets/toc.css` 176 | 177 |
178 | 179 |

180 | 181 |
182 | 183 | ```css 184 | /* 185 | Snippet: Table of Contents > v2 186 | */ 187 | 188 | /* 189 | toc > header 2 190 | */ 191 | 192 | .toc_h2 a 193 | { 194 | color: #7fa8f5 !important; 195 | font-size: 10pt; 196 | font-weight: lighter; 197 | line-height: 20px; 198 | } 199 | 200 | /* 201 | toc > header 3 202 | */ 203 | 204 | .toc_h3 a 205 | { 206 | color: #f85289 !important; 207 | font-size: 9pt; 208 | font-weight: lighter; 209 | line-height: 20px; 210 | } 211 | 212 | /* 213 | toc > header 4, 5, 6 214 | */ 215 | 216 | .toc_h4 a, .toc_h5 a, .toc_h6 a 217 | { 218 | color: #969696 !important; 219 | font-size: 8pt; 220 | font-weight: normal; 221 | line-height: 20px; 222 | } 223 | 224 | /* 225 | toc > bad links > path 226 | */ 227 | 228 | .toc_badpaths_path, .toc_badpaths_path a 229 | { 230 | color: #adadad !important; 231 | font-size: 8pt; 232 | font-weight: normal; 233 | line-height: 20px; 234 | } 235 | 236 | /* 237 | toc > no results 238 | */ 239 | 240 | .toc_results_none 241 | { 242 | text-align: center; 243 | font-size: 12pt; 244 | } 245 | ``` 246 | 247 |
248 | 249 | Save the file and go back to **Obsidian Settings** -> **Appearance**. Scroll all the way down and enable the checkbox to the right of `toc.css`. 250 | 251 |

252 | 253 |
254 | 255 | You should see a table of contents which is populated with the headings of your subfolders. 256 | 257 |

258 | 259 | --- 260 | 261 |

262 | 263 | ## Customization 264 | ### How to make page title above the each list appear bigger 265 | In your code, locate 266 | ```javascript 267 | dv.header(4, p.file.name); 268 | ``` 269 | 270 | The `4` stands for `H4` or header 4. To make the text bigger, change that number to `3 or lower`. Overall, it accepts any number between `1 - 6`, with 1 being the biggest and 6 being the smallest text size. 271 | 272 |
273 |
274 | 275 | ### Make each page title not display as a listed item 276 | Locate the code toward the top: 277 | ```javascript 278 | dv.header(4, p.file.name); 279 | ``` 280 | and replace it with: 281 | ```javascript 282 | dv.el("div", p.file.name); 283 | ``` 284 | 285 | This will force each page title to display in a `div` and not as header object. 286 | 287 |
288 |
289 | 290 | ### My list is cutting off the first header of each page 291 | Locate the following code: 292 | ```javascript 293 | const houtput = headings.slice(1) 294 | ``` 295 | 296 | The number `1` represents how many headers on the page that should be excluded from the first going from the top down. If you enter the number `0`, then no headers will be filtered out / all will show in the list. If you enter `3`, then the first three headers of each page will not appear in the table of contents list. 297 | 298 | To disable any headers from being excluded in the list, change the code above to the following: 299 | ```javascript 300 | const houtput = headings.slice(0) 301 | ``` 302 | 303 |
304 |
305 | 306 | ### Exclude certain headers from appearing in the list 307 | Much like the example above which allows you to filter from from the top, you can also filter exactly which headers display in the list with the following code: 308 | ```javascript 309 | .filter(h => h.level <= 6) 310 | ``` 311 | 312 | The number `6` represents which headers will be included in the list. If you change the value to a `4`, that means any sections of your page with headers 5 or 6 will not show. 313 | ``` 314 | ##### This is H5 315 | ###### This is H6 316 | ``` 317 | 318 |
319 |
320 | 321 | ### Making the gap between each list smaller/bigger 322 | You need to modify the following: 323 | ```javascript 324 | dv.el("div", "

"); 325 | ``` 326 | Each `
` is a line break. The more breaks you add, the larger the gap between each list. Remove each break to make the gap smaller. 327 | 328 |
329 |
-------------------------------------------------------------------------------- /Snippets/TOC Version 2/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 2/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/TOC Version 2/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 2/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/TOC Version 2/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 2/images/install_2.png -------------------------------------------------------------------------------- /Snippets/TOC Version 2/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/TOC Version 2/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 1/README.md: -------------------------------------------------------------------------------- 1 | # Obsidian: Tag Cloud : Version 1 2 | This snippet requires a copy of [Obsidian.md](obsidian.md/) 3 |
4 | This snippet requires the [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview). 5 | 6 |

7 | 8 | ## About 9 | The `Tag Cloud` snippet will fetch a list of your vault's current tags and display them in a colorful list. 10 | 11 |
12 | 13 | At the time of writing this script, I am using the following: 14 | 15 | | Software | Version | 16 | | --- | --- | 17 | | [Obsidian.md](https://obsidian.md/) | ![GitHub release](https://img.shields.io/github/v/release/obsidianmd/obsidian-releases?label=v&color=ba0f56) | 18 | | [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) | ![GitHub release](https://img.shields.io/github/v/release/blacksmithgu/obsidian-dataview?label=v&color=ba0f56) | 19 | 20 |

21 | 22 | > [!WARNING] WARNING - Using Special Characters In Tags 23 | > Obsidian currently doesn't support using periods within tags. If you have any tags that contain a period, your tag list may not render. 24 | > 25 | > ex: `#my.tag` 26 | 27 |
28 | 29 | ### Previews 30 | The following are preview images of what the snippet will do and appear like: 31 | 32 |
33 | 34 |

35 | 36 |

37 | 38 | --- 39 | 40 |

41 | 42 | ## Usage 43 | 44 | - Install [Dataview Plugin](https://github.com/blacksmithgu/obsidian-dataview) 45 | - Copy the code below and paste it in a note. 46 | 47 |
48 | 49 | ````shell 50 | ```dataviewjs 51 | /* 52 | Snippet: Tag Cloud - Version 1 53 | 54 | This snippet requires the Dataview Plugin 55 | https://github.com/blacksmithgu/obsidian-dataview 56 | 57 | View settings at: 58 | https://github.com/Aetherinox/obsidian-dataview-snippets/tree/main/Snippets/Tag%20Cloud%201 59 | */ 60 | 61 | /* 62 | Settings 63 | */ 64 | 65 | const QueryStr = `""`; 66 | const QueryFiles = dv.pages( QueryStr ); 67 | 68 | const bRandomColor = true; 69 | const sortOption = 1; 70 | const weightBacklinks = 0.1; 71 | const weightWordCount = 0.05; 72 | const minFontSize = 12; 73 | const maxFontSize = 36; 74 | const tagsFilter = [ "#tag1", "#tag2" ]; 75 | const arrColors = []; 76 | 77 | dv.container.className += ' atx-tcv1-dataview' 78 | 79 | /* 80 | Generate 40 colors 81 | */ 82 | 83 | for ( let i = 0; i < 40; i++ ) 84 | { 85 | 86 | let R = Math.floor( ( Math.random( ) * 100 ) + 100 ); 87 | let G = Math.floor( ( Math.random( ) * 100 ) + 100 ); 88 | let B = Math.floor( ( Math.random( ) * 100 ) + 100 ); 89 | 90 | let rgb = ( R << 16 ) + ( G << 8 ) + B; 91 | let itemColor = `#${rgb.toString( 16 )}`; 92 | 93 | arrColors.push( itemColor ); 94 | } 95 | 96 | /* 97 | Get all backlinks 98 | */ 99 | 100 | async function QueryBacklinks( q ) 101 | { 102 | const file = q.split( '/' ).pop( ).split( "." ).slice( 0, -1 ).join( "." ); 103 | return dv.query( 104 | ` 105 | LIST 106 | FROM [[${file}]] AND ${QueryStr} 107 | SORT file.name DESC 108 | ` 109 | ); 110 | } 111 | 112 | /* 113 | Get number of words in each file 114 | */ 115 | 116 | async function QueryWordcount( q ) 117 | { 118 | const fs = require( 'fs' ); 119 | const path = require( 'path' ); 120 | const text = fs.readFileSync( path.join( app.vault.adapter.basePath, q ), 'utf-8' ); 121 | const pattern = /---[\s\S]*?---|```[\s\S]*?```|\$[\s\S]*?\$|\$\$[\s\S]*?\$\$/g; 122 | const cleanedText = text.replace( pattern, '' ); 123 | const matchText = cleanedText.match( /\S+/g ); 124 | 125 | if ( !matchText ) 126 | return 0; 127 | 128 | return matchText.length; 129 | } 130 | 131 | /* 132 | Calculate font text size which is determined by number of backlinks 133 | and number of words available. 134 | */ 135 | 136 | function Generate_FontSize( backlinks, wordCount ) 137 | { 138 | const calcFontSize = Math.sqrt( ( backlinks * weightBacklinks ) + ( wordCount * weightWordCount ) ) * 2.5; 139 | return Math.round( ( calcFontSize / 100 ) * ( maxFontSize - minFontSize ) + minFontSize ); 140 | } 141 | 142 | /* 143 | Generate font color 144 | */ 145 | 146 | function Generate_Color( tagName, tagInfo ) 147 | { 148 | if ( tagName == null ) { return "#FFFFFF"; } 149 | 150 | let cntColors = Object.keys( arrColors ).length; 151 | const tagWords = tagName.split(/\W+/g); 152 | const colorIndex = Math.floor( Math.random( ) * cntColors ); 153 | const colorID = dv.pages( tagName ).length; 154 | 155 | if ( bRandomColor === true ) 156 | return arrColors[ Object.keys( arrColors )[ colorIndex ] ]; 157 | 158 | return arrColors[ Object.keys( arrColors )[ colorID ] ]; 159 | } 160 | 161 | /* 162 | Sort > DESC / ASC 163 | 164 | alphabetize array results 165 | */ 166 | 167 | function Sort_DESC( arr ) 168 | { 169 | arr.sort( ( a, b ) => a.id.localeCompare( b.id ) ) 170 | return arr; 171 | } 172 | 173 | function Sort_ASC( arr ) 174 | { 175 | arr.sort( ( a, b ) => b.id.localeCompare( a.id ) ) 176 | return arr; 177 | } 178 | 179 | /* 180 | Sort > Shuffle 181 | 182 | randomized array results 183 | */ 184 | 185 | function Sort_Shuffle( arr ) 186 | { 187 | for ( let i = arr.length - 1; i > 0; i-- ) 188 | { 189 | const j = Math.floor( Math.random( ) * ( i + 1 ) ); 190 | [ arr[ i ], arr[ j ] ] = [ arr[ j ], arr[ i ] ]; 191 | } 192 | 193 | return arr; 194 | } 195 | 196 | /* 197 | Create Cloud 198 | */ 199 | 200 | const CreateTagCloud = async ( ) => 201 | { 202 | const tags = new Map( ); 203 | const files = new Map( ); 204 | 205 | /* 206 | Add all .md files to the tags map with their backlinks and word count 207 | */ 208 | 209 | Promise.all( QueryFiles.map( async ( f ) => 210 | { 211 | const file = f.file 212 | const blq = QueryBacklinks( file.path ) 213 | const wcq = QueryWordcount( file.path ) 214 | 215 | if ( file.tags ) 216 | { 217 | await Promise.all( file.tags.map( async ( tag ) => 218 | { 219 | if ( !tags.has( tag ) ) 220 | tags.set( tag, { backlinks: 0, wordCount: 0 } ); 221 | 222 | const tagInfo = tags.get( tag ); 223 | const res = await blq; 224 | 225 | tagInfo.backlinks += res.value.values.length; 226 | 227 | const wc = await wcq; 228 | tagInfo.wordCount += wc; 229 | } ) ); 230 | } 231 | 232 | for ( let i = 0; i < tagsFilter.length; i++ ) 233 | { 234 | if ( tags.has( tagsFilter[ i ] ) ) 235 | tags.delete( tagsFilter[ i ] ); 236 | } 237 | 238 | const fileInfo = { backlinks: 0, wordCount: 0 }; 239 | const res = await blq; 240 | fileInfo.backlinks = res.value.values.length; 241 | const wc = await wcq; 242 | fileInfo.wordCount = wc; 243 | 244 | files.set( file, fileInfo ); 245 | 246 | })).then( ( ) => 247 | { 248 | const data = [] 249 | 250 | /* 251 | Calculate font size and font color. 252 | */ 253 | 254 | let count = 0; 255 | tags.forEach( ( tagInfo, tagName ) => 256 | { 257 | count++; 258 | const fontSize = Generate_FontSize( tagInfo.backlinks, tagInfo.wordCount ); 259 | const color = Generate_Color( tagName, tagInfo ); 260 | const length = dv.pages( tagName ).length; 261 | 262 | data.push( { name: `\\${tagName}`, id: tagName, length: length, fontSize, color } ); 263 | }); 264 | 265 | /* 266 | No tags found 267 | */ 268 | 269 | if (count === 0) 270 | { 271 | const rootNode = dv.el("div", "🔖 No Tags Found", { cls: "atx-tcv1-results_none" }); 272 | rootNode.setAttribute("style", "text-align:center;"); 273 | return ``; 274 | } 275 | 276 | /* 277 | Sorting functions 278 | */ 279 | 280 | const sortOptions = 281 | { 282 | 1: 'Sort_DESC', 283 | 2: 'Sort_ASC', 284 | 3: 'Sort_Shuffle', 285 | }; 286 | 287 | let funcSort = sortOptions[ sortOption ] 288 | 289 | if ( funcSort === undefined ) 290 | funcSort = sortOptions[ 1 ] 291 | 292 | /* 293 | Return results 294 | */ 295 | 296 | return eval( funcSort )( data ).map( ( tag ) => 297 | { 298 | return `
${tag.id}
${tag.length}
`; 299 | } ).join( "" ); 300 | } ).then( res => dv.paragraph( res ) ) 301 | .catch( error => 302 | { 303 | console.error( "Error: " + error ); 304 | } ); 305 | } 306 | 307 | CreateTagCloud( ) 308 | ``` 309 | ```` 310 | 311 |
312 | 313 | #### Minified Version 314 | This version only formats the settings. All other formatting and comments are removed. 315 | 316 |
317 | 318 | ````shell 319 | ```dataviewjs 320 | const QueryStr = `""`; 321 | const QueryFiles = dv.pages( QueryStr ); 322 | 323 | const bRandomColor = true; 324 | const sortOption = 1; 325 | const weightBacklinks = 0.1; 326 | const weightWordCount = 0.05; 327 | const minFontSize = 12; 328 | const maxFontSize = 36; 329 | const tagsFilter = [ "#tag1", "#tag2" ]; 330 | 331 | const arrColors=[];dv.container.className+=" atx-tcv1-dataview";for(let t=0;t<40;t++){let t=Math.floor(100*Math.random()+100),o=Math.floor(100*Math.random()+100),e=Math.floor(100*Math.random()+100),a=(t<<16)+(o<<8)+e,n=`#${a.toString(16)}`;arrColors.push(n)}async function QueryBacklinks(t){const o=t.split("/").pop().split(".").slice(0,-1).join(".");return dv.query(`\n LIST\n FROM [[${o}]] AND ${QueryStr}\n SORT file.name DESC\n `)}async function QueryWordcount(t){const o=require("fs"),e=require("path"),a=o.readFileSync(e.join(app.vault.adapter.basePath,t),"utf-8").replace(/---[\s\S]*?---|```[\s\S]*?```|\$[\s\S]*?\$|\$\$[\s\S]*?\$\$/g,"").match(/\S+/g);return a?a.length:0}function Generate_FontSize(t,o){const e=2.5*Math.sqrt(t*weightBacklinks+o*weightWordCount);return Math.round(e/100*(maxFontSize-minFontSize)+minFontSize)}function Generate_Color(t,o){if(null==t)return"#FFFFFF";let e=Object.keys(arrColors).length;t.split(/\W+/g);const a=Math.floor(Math.random()*e),n=dv.pages(t).length;return!0===bRandomColor?arrColors[Object.keys(arrColors)[a]]:arrColors[Object.keys(arrColors)[n]]}function Sort_DESC(t){return t.sort(((t,o)=>t.id.localeCompare(o.id))),t}function Sort_ASC(t){return t.sort(((t,o)=>o.id.localeCompare(t.id))),t}function Sort_Shuffle(t){for(let o=t.length-1;o>0;o--){const e=Math.floor(Math.random()*(o+1));[t[o],t[e]]=[t[e],t[o]]}return t}const CreateTagCloud=async()=>{const tags=new Map,files=new Map;Promise.all(QueryFiles.map((async t=>{const o=t.file,e=QueryBacklinks(o.path),a=QueryWordcount(o.path);o.tags&&await Promise.all(o.tags.map((async t=>{tags.has(t)||tags.set(t,{backlinks:0,wordCount:0});const o=tags.get(t),n=await e;o.backlinks+=n.value.values.length;const r=await a;o.wordCount+=r})));for(let t=0;t{const data=[];let count=0;if(tags.forEach(((t,o)=>{count++;const e=Generate_FontSize(t.backlinks,t.wordCount),a=Generate_Color(o,t),n=dv.pages(o).length;data.push({name:`\\${o}`,id:o,length:n,fontSize:e,color:a})})),0===count){const t=dv.el("div","🔖 No Tags Found",{cls:"atx-tcv1-results_none"});return t.setAttribute("style","text-align:center;"),""}const sortOptions={1:"Sort_DESC",2:"Sort_ASC",3:"Sort_Shuffle"};let funcSort=sortOptions[sortOption];return void 0===funcSort&&(funcSort=sortOptions[1]),eval(funcSort)(data).map((t=>`
${t.id}
${t.length}
`)).join("")})).then((t=>dv.paragraph(t))).catch((t=>{console.error("Error: "+t)}))};CreateTagCloud(); 332 | ``` 333 | ```` 334 | 335 |

336 | 337 |
338 | 339 | **[`^ back to top ^`](#table-of-contents-)** 340 | 341 |
342 | 343 |

344 | 345 | --- 346 | 347 |

348 | 349 | Next, you need to add some custom CSS. 350 | Open Obsidian Settings, click **Appearance**, and then scroll all the way down. (See image below). 351 | 352 | Click the mini folder icon to open your **Obsidian Snippets folder**. 353 | 354 |
355 | 356 |

357 | 358 |
359 | 360 | Create a new file named whatever (`tag_cloud_v1.css` in our example). 361 | 362 | Copy the code below and paste it into the new `tag_cloud_v1.css` file which should be in `YourVaultName/.obsidian/snippets/tag_cloud_v1.css` 363 | 364 |
365 | 366 |

367 | 368 |
369 | 370 | ```css 371 | /* 372 | Snippet: Tag Cloud - Version 1 373 | */ 374 | 375 | /* 376 | animation: glow 377 | */ 378 | 379 | @keyframes anim_glow 380 | { 381 | from 382 | { 383 | text-shadow: 0 0 110px #6f00ff, 0 0 120px #0084ff, 0 0 130px #e60073, 0 0 140px #e60073, 0 0 150px #e60073, 0 0 160px #e60073, 0 0 170px #e60073; 384 | } 385 | to 386 | { 387 | text-shadow: 0 0 20px #6f00ff, 0 0 30px #ff4da6, 0 0 40px #ff4da6, 0 0 50px #ff4da6, 0 0 60px #ff4da6, 0 0 70px #ff4da6, 0 0 80px #ff4da6; 388 | } 389 | } 390 | 391 | /* 392 | animation: pulse 393 | */ 394 | 395 | @keyframes pulse 396 | { 397 | 0% 398 | { 399 | transform: scale(0.85); 400 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7); 401 | } 402 | 403 | 70% 404 | { 405 | transform: scale(1); 406 | box-shadow: 0 0 0 10px rgba(0, 0, 0, 0); 407 | } 408 | 409 | 100% 410 | { 411 | transform: scale(0.85); 412 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); 413 | } 414 | } 415 | 416 | /* 417 | Dataview parent div 418 | */ 419 | 420 | .atx-tcv1-dataview 421 | { 422 | padding-left: var( --atx-tcv2-general-container-padding ); 423 | padding-right: var( --atx-tcv2-general-container-padding ); 424 | padding-top: 20px; 425 | padding-bottom: 20px; 426 | } 427 | 428 | /* 429 | Tag Cloud > Item 430 | */ 431 | 432 | .cloudtags-v1-item 433 | { 434 | margin-top: 5px; 435 | margin-bottom: 5px; 436 | margin-left: 7px; 437 | margin-right: 7px; 438 | padding-left: 7px; 439 | padding-right: 7px; 440 | padding-top: 4px; 441 | padding-bottom: 4px; 442 | background-color: #252525; 443 | border: 1px solid #353535 !important; 444 | border-radius: 6px; 445 | display: inline-block; 446 | font-weight: bold; 447 | position: relative; 448 | } 449 | 450 | .cloudtags-v1-item:hover 451 | { 452 | opacity: 1; 453 | background: #810d3d; 454 | border: 1px solid #dd2a74 !important; 455 | cursor: pointer; 456 | animation-name: pulse, anim_glow; 457 | animation-duration: 2s, 1s; 458 | animation-timing-function: ease, ease-in-out; 459 | animation-iteration-count: infinite, infinite; 460 | animation-direction: normal, alternate; 461 | } 462 | 463 | .cloudtags-v1-item:hover a 464 | { 465 | color: #FFF !important; 466 | background: none; 467 | } 468 | 469 | /* 470 | Tag Cloud > Links 471 | */ 472 | 473 | a.cloudtags-v1-link 474 | { 475 | line-height: 30px; 476 | vertical-align: middle; 477 | text-decoration: none; 478 | } 479 | 480 | /* 481 | Tag Cloud > Length 482 | */ 483 | 484 | .tagcloud-v1-length 485 | { 486 | border-radius: 50%; 487 | width: 18px; 488 | height: 18px; 489 | background: #424242; 490 | color: #FFF; 491 | text-align: center; 492 | font: 8px sans-serif; 493 | position: absolute; 494 | vertical-align: middle; 495 | margin: auto 0; 496 | left: 3%; 497 | top: -5px; 498 | transform: translateX(-50%); 499 | line-height: 19px; 500 | } 501 | 502 | /* 503 | Tag Cloud > No results 504 | */ 505 | 506 | .atx-tcv1-results_none 507 | { 508 | text-align: center; 509 | font-size: 14pt; 510 | } 511 | 512 | .atx-tcv1-results_none_subheader 513 | { 514 | padding-left: 12px; 515 | font-size: 10pt; 516 | } 517 | ``` 518 | 519 |
520 | 521 | Save the file and go back to **Obsidian Settings** -> **Appearance**. Scroll all the way down and enable the checkbox to the right of `tag_cloud_v1.css`. 522 | 523 |

524 | 525 |
526 | 527 | You should see a list of tags associated to your vault. 528 | 529 |

530 | 531 | --- 532 | 533 |

534 | 535 | ## Customization 536 | The section below explains how to customize this snippet. 537 | 538 |
539 | 540 | ### Filtering Folders, Pages & Tags 541 | This snippet allows you to filter out folders, pages and tags which will not be included in your list of generated tags that appear in your cloud. The syntax is the same as normal Dataview queries. 542 | 543 | To filter out folders or pages, edit the following: 544 | 545 | ```javascript 546 | const QueryStr = `""`; 547 | ``` 548 | 549 |
550 | 551 | #### Exclude Folders 552 | 553 | To filter out or exclude the folder `"My Personal Stuff"`, and all notes in that folder; use the following: 554 | 555 | ```javascript 556 | const QueryStr = `-"My Personal Stuff"`; 557 | ``` 558 | 559 | The folder name **must** be enclosed in quotation marks `"`. 560 | 561 |
562 | 563 | The `-` character represents an `exclude`, and must be used OUTSIDE the quotation marks. 564 | 565 |
566 | 567 | To exclude multiple folders, add `AND` between each folder. 568 | 569 | ```javascript 570 | const QueryStr = `-"My Personal Stuff" AND `-"Another Folder"`; 571 | ``` 572 | 573 |
574 |
575 | 576 | #### Exclude Page 577 | To filter out a specific file or page, it is similar to the above, except you must provide the full path to the page, including the folder. 578 | 579 |
580 | 581 | For example, if you have a folder named `Personal Stuff`, and a page inside called `My Pin Codes`, you can exclude it using: 582 | 583 | ```javascript 584 | const QueryStr = `-"Personal Stuff/My PIN Codes"`; 585 | ``` 586 | 587 |
588 |
589 | 590 | #### Exclude Tags 591 | To filter out specific tags, this is done slightly different than the other options above. You can prevent certain tags from appearing in your cloud by modifying the following property: 592 | 593 |
594 | 595 | ```javascript 596 | const tagsFilter = [ "#tag1", "#tag2" ]; 597 | ``` 598 | 599 |
600 | 601 | Ensure you use the structure provided. Each tag must be wrapped in quotation marks `"`, with a comma `,` separating each one. 602 | 603 |
604 |
605 | 606 | ### Change Sorting 607 | This snippet allows for three ways of sorting tags: 608 | 1. Alphabetically (Descending A-Z) 609 | 2. Alphabetically (Ascending Z-A) 610 | 3. Random / Shuffle 611 | 612 |
613 | 614 | To change the sorting, edit the property: 615 | 616 | ```javascript 617 | const sortOption = 1; 618 | ``` 619 | 620 |
621 |
622 | 623 | ### Random Tag Colors 624 | Tags can either be assigned random colors, or colors can be assigned depending on how many times that tag has been called. 625 | 626 |
627 | 628 | To change this, edit the property: 629 | 630 | ```javascript 631 | const bRandomColor = true; 632 | ``` 633 | 634 |
635 |
636 | 637 | ### Font Size 638 | The font size of a tag is determined by two things: 639 | 1. Number of times a tag is used 640 | 2. Number of words associated to a tag. 641 | 642 |
643 | 644 | To limit the font sizes that are used, edit the two properties below: 645 | 646 | ```javascript 647 | const minFontSize = 12; 648 | const maxFontSize = 32; 649 | ``` 650 | 651 |
652 |
653 | 654 | ### Font Weight 655 | The font weight of a tag is determined by two things: 656 | 1. Number of times a tag is used 657 | 2. Number of words associated to a tag. 658 | 659 |
660 | 661 | To limit the font weight sizes used, edit the two properties below. The lower the value, the thinner the tag. Higher numbers will display more bold text. This setting also plays a role in the [Font Size](#font-size) 662 | 663 | ```javascript 664 | const weightBacklinks = 0.1; 665 | const weightWordCount = 0.3; 666 | ``` 667 | 668 |
669 |
670 | 671 | ### Cloud Colors 672 | As of `v1.3.0`, this snippet auto generates the colors that will be used for each tag listed in the cloud. The color generation code will keep the color tones in the **pastel** range, and will exclude darker colors since the background box color is dark. 673 | 674 |
675 | 676 | To modify the color range, edit the following code: 677 | 678 | ```javascript 679 | let R = Math.floor( ( Math.random( ) * 100 ) + 100 ); 680 | let G = Math.floor( ( Math.random( ) * 100 ) + 100 ); 681 | let B = Math.floor( ( Math.random( ) * 100 ) + 100 ); 682 | ``` 683 | 684 |
685 | 686 | For brighter colors, increase `100`. Don't exceed `255`. 687 | 688 | For darker colors, decrease `100`. Don't go below `0`. 689 | -------------------------------------------------------------------------------- /Snippets/Tag Cloud 1/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 1/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 1/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 1/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 1/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 1/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Tag Cloud 1/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 1/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 2/images/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 2/images/example_1.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 2/images/install_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 2/images/install_1.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 2/images/install_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 2/images/install_2.png -------------------------------------------------------------------------------- /Snippets/Tag Cloud 2/images/install_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 2/images/install_3.gif -------------------------------------------------------------------------------- /Snippets/Tag Cloud 2/images/install_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aetherinox/obsidian-dataview-snippets/8db4ac9a0753363a7140c0af35cdeb0128b15ee3/Snippets/Tag Cloud 2/images/install_4.gif -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | const tsParser = require('@typescript-eslint/parser'); 2 | const js = require('@eslint/js'); 3 | const globals = require('globals'); 4 | const ts = require('@typescript-eslint/eslint-plugin'); 5 | const eslintConfigPrettier = require('eslint-config-prettier'); 6 | const prettier = require('eslint-plugin-prettier'); 7 | const stylisticJs = require('@stylistic/eslint-plugin-js'); 8 | const stylisticTs = require('@stylistic/eslint-plugin-ts'); 9 | const stylisticPlus = require('@stylistic/eslint-plugin-plus') 10 | 11 | module.exports = [ 12 | { 13 | files: [ 14 | '**/*.ts', 15 | './src/**/*.ts', 16 | './test/**/*.ts' 17 | ], 18 | plugins: { 19 | '@typescript-eslint': ts, 20 | 'prettier': prettier, 21 | '@stylistic/js': stylisticJs, 22 | '@stylistic/ts': stylisticTs, 23 | '@stylistic/plus': stylisticPlus 24 | }, 25 | languageOptions: { 26 | parser: tsParser, 27 | globals: { 28 | ...globals.browser, 29 | }, 30 | parserOptions: { 31 | project: ['tsconfig.json'], 32 | }, 33 | }, 34 | rules: { 35 | ...js.configs.recommended.rules, 36 | ...ts.configs['stylistic-type-checked'].rules, 37 | // eslint/js rules 38 | 'indent': [1, 4], 39 | 'space-before-function-paren': 0, 40 | 'prefer-const': 1, 41 | 'comma-dangle': 0, 42 | 'keyword-spacing': ['error', { before: true, after: true }], 43 | 'comma-spacing': ['error', { before: false, after: true }], 44 | 'indent': 0, 45 | 'prefer-spread': 1, 46 | 'eqeqeq': ['error', 'smart'], 47 | 'no-unexpected-multiline': 0, 48 | 'no-prototype-builtins': 0, 49 | 'no-useless-escape': 1, 50 | 'no-mixed-operators': 1, 51 | 'no-control-regex': 0, 52 | 'no-console': 2, 53 | 'no-var': 2, 54 | 'no-undef': 0, 55 | 'no-redeclare': 'error', 56 | 'no-unused-vars': [ 57 | 'error', 58 | { 59 | 'argsIgnorePattern': '^_', 60 | 'varsIgnorePattern': '^_', 61 | 'ignoreRestSiblings': true 62 | } 63 | ], 64 | 65 | '@stylistic/js/no-multi-spaces': [ 0, { ignoreEOLComments: true } ], 66 | '@stylistic/js/arrow-spacing': [ 'error', { before: true, after: true } ], 67 | '@stylistic/js/arrow-parens': [ 'error', 'always' ], 68 | 69 | '@stylistic/js/block-spacing': [ 'error', 'always' ], 70 | '@stylistic/ts/block-spacing': [ 'error', 'always' ], 71 | 72 | '@stylistic/js/brace-style': [ 'error', 'allman', { allowSingleLine: true } ], 73 | '@stylistic/ts/brace-style': [ 'error', 'allman', { allowSingleLine: true } ], 74 | 75 | '@stylistic/js/comma-dangle': [ 'error', 'never' ], 76 | '@stylistic/ts/comma-dangle': [ 'error', 'never' ], 77 | 78 | '@stylistic/js/comma-spacing': [ 'error', { before: false, after: true }], 79 | '@stylistic/ts/comma-spacing': [ 'error', { before: false, after: true }], 80 | 81 | '@stylistic/js/keyword-spacing': [ 'error', { 82 | before: true, 83 | after: true, 84 | 'overrides': 85 | { 86 | return: { before: true, after: true }, 87 | throw: { before: true, after: true }, 88 | case: { before: true, after: true }, 89 | as: { before: true, after: true }, 90 | if: { before: true, after: true }, 91 | for: { before: true, after: true }, 92 | while: { before: true, after: true }, 93 | static: { before: true, after: true } 94 | }, 95 | }], 96 | 97 | '@stylistic/ts/keyword-spacing': ['error', { 98 | before: true, 99 | after: true, 100 | 'overrides': 101 | { 102 | return: { before: true, after: true }, 103 | throw: { before: true, after: true }, 104 | case: { before: true, after: true }, 105 | as: { before: true, after: true }, 106 | if: { before: true, after: true }, 107 | for: { before: true, after: true }, 108 | while: { before: true, after: true }, 109 | static: { before: true, after: true } 110 | }, 111 | }], 112 | 113 | '@stylistic/js/computed-property-spacing': ['error', 'always'], 114 | '@stylistic/js/eol-last': ['error', 'always'], 115 | '@stylistic/js/jsx-quotes': ['error', 'prefer-single'], 116 | '@stylistic/js/linebreak-style': ['error', 'unix'], 117 | '@stylistic/js/no-mixed-spaces-and-tabs': ['error'], 118 | '@stylistic/js/no-tabs': ['error'], 119 | '@stylistic/js/no-trailing-spaces': ['error', { 'skipBlankLines': true, 'ignoreComments': true }], 120 | '@stylistic/js/no-whitespace-before-property': ['error'], 121 | 122 | '@stylistic/js/object-curly-spacing': ['error', 'always'], 123 | '@stylistic/ts/object-curly-spacing': ['error', 'always'], 124 | 125 | '@stylistic/js/quote-props': ['error', 'as-needed'], 126 | '@stylistic/ts/quote-props': ['error', 'as-needed'], 127 | 128 | '@stylistic/js/quotes': ['error', 'single', { 'allowTemplateLiterals': true }], 129 | '@stylistic/ts/quotes': ['error', 'single', { 'allowTemplateLiterals': true }], 130 | 131 | '@stylistic/js/semi': ['error', 'never'], 132 | '@stylistic/ts/semi': ['error', 'never'], 133 | 134 | '@stylistic/js/space-in-parens': ['error', 'always'], 135 | 136 | '@stylistic/js/space-infix-ops': ['error'], 137 | '@stylistic/ts/space-infix-ops': ['error'], 138 | 139 | '@stylistic/js/spaced-comment': ['error', 'always'], 140 | '@stylistic/js/template-curly-spacing': ['error', 'always'], 141 | '@stylistic/js/template-tag-spacing': ['error', 'always'], 142 | '@stylistic/js/wrap-iife': [2, "inside", { functionPrototypeMethods: true }], 143 | 144 | '@stylistic/plus/type-named-tuple-spacing': ["error"], 145 | '@stylistic/plus/type-generic-spacing': ["error"], 146 | 147 | // 'prettier/prettier': ['error'], 148 | // @typescript-eslint rules 149 | '@typescript-eslint/prefer-nullish-coalescing': 'off' // require `strictNullChecks` 150 | }, 151 | }]; 152 | -------------------------------------------------------------------------------- /obs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* eslint-disable @typescript-eslint/no-var-requires */ 3 | 4 | /* 5 | build obs by running 6 | npm run build 7 | 8 | guid and uuid will be automatically generated and placed 9 | inside .env file which will then be read by the github workflow 10 | build script. 11 | */ 12 | 13 | /* 14 | This script handles the following: 15 | - read package.json 16 | - create .env file 17 | - return uuid, guid, version 18 | 19 | can be called with the following external commands: 20 | - node obs.js returns version of obs 21 | - node obs.js generate generates uuid / guid and shows all env vars in console 22 | - node obs.js uuid returns obs uuid 23 | - node obs.js guid returns obs guid 24 | - node obs.js versiom returns version of obs 25 | 26 | can be called with the following obs commands: 27 | - npm run obs 28 | - npm run obs:generate 29 | - npm run env-obs 30 | - npm run env-uuid 31 | - npm run env-guid 32 | - npm run env-version 33 | */ 34 | 35 | const fs = require('fs'); 36 | const { v5: uuid } = require('uuid'); 37 | 38 | /* 39 | * declrations > package.json 40 | */ 41 | 42 | const { version, repository } = JSON.parse(fs.readFileSync('package.json')); 43 | const args = process.argv.slice(2, process.argv.length); 44 | const action = args[0]; 45 | // const a = args[ 1 ]; 46 | // const b = args[ 2 ]; 47 | 48 | if (action === 'guid') { 49 | console.log(`${process.env.GUID}`); 50 | } else if (action === 'setup') { 51 | fs.writeFileSync('.env', '', (err) => { 52 | if (err) { 53 | console.error(err); 54 | } else { 55 | console.log(`Wrote to .env successfully`); 56 | } 57 | }); 58 | } else if (action === 'generate') { 59 | const buildGuid = uuid(`${repository.url}`, uuid.URL); 60 | const buildUuid = uuid(version, buildGuid); 61 | 62 | const ids = ` 63 | VERSION=${version} 64 | GUID=${buildGuid} 65 | UUID=${buildUuid} 66 | `; 67 | 68 | console.log(version); 69 | console.log(buildGuid); 70 | console.log(buildUuid); 71 | 72 | fs.writeFileSync('.env', ids, (err) => { 73 | if (err) { 74 | console.error(`Could not write env vars: ${err}`); 75 | } else { 76 | console.log(`Wrote env vars to .env`); 77 | } 78 | }); 79 | } else if (action === 'uuid') { 80 | console.log(`${process.env.UUID}`); 81 | } else { 82 | console.log(version); 83 | } 84 | 85 | process.exit(0); 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aetherinox/obsidian-dataview-snippets", 3 | "version": "1.4.3", 4 | "description": "A collection of Obsidian.md scripts to be used in combination with the dataview plugin.", 5 | "homepage": "https://github.com/Aetherinox/obsidian-dataview-snippets", 6 | "author": "Aetherinox ", 7 | "license": "MIT", 8 | "contributors": [ 9 | { 10 | "name": "Aetherinox", 11 | "email": "118329232+Aetherinox@users.noreply.github.com", 12 | "url": "https://github.com/Aetherinox" 13 | }, 14 | { 15 | "name": "EuropaServ", 16 | "email": "161414668+EuropaServ@users.noreply.github.com", 17 | "url": "https://github.com/EuropaServ" 18 | } 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/Aetherinox/obsidian-dataview-snippets.git" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/Aetherinox/obsidian-dataview-snippets/issues" 26 | }, 27 | "build": { 28 | "appId": "com.obsidian.dataview.snippets.id" 29 | }, 30 | "funding": [ 31 | { 32 | "type": "individual", 33 | "url": "https://buymeacoffee.com/aetherinox" 34 | } 35 | ], 36 | "keywords": [ 37 | "obsidian", 38 | "dataview", 39 | "folder_notes", 40 | "snippets", 41 | "scripts", 42 | "notes" 43 | ], 44 | "scripts": { 45 | "pretest": "npm run lint", 46 | "lint": "eslint src/**/*.ts", 47 | "lint:fix": "eslint --fix src/**/*.ts", 48 | "pretty": "prettier . --check", 49 | "pretty:fix": "prettier . --write", 50 | "pretty:ignore": "prettier . --write --ignore-unknown", 51 | "obs": "node obs.js", 52 | "contrib:add": "all-contributors add", 53 | "contrib:generate": "all-contributors generate", 54 | "root": "node obs.js", 55 | "root:generate": "node obs.js generate", 56 | "env:obs": "npx --quiet env-cmd --no-override node obs.js", 57 | "env:uuid": "npx --quiet env-cmd --no-override node obs.js uuid", 58 | "env:guid": "npx --quiet env-cmd --no-override node obs.js guid", 59 | "env:version": "node -p require('./package.json').version;" 60 | }, 61 | "devDependencies": { 62 | "eslint-plugin-prettier": "^5.2.1", 63 | "typescript-eslint": "^7.14.0", 64 | "@typescript-eslint/parser": "^7.16.0", 65 | "@typescript-eslint/eslint-plugin": "^7.16.0", 66 | "@stylistic/eslint-plugin-js": "^2.3.0", 67 | "@stylistic/eslint-plugin-ts": "^2.3.0", 68 | "@stylistic/eslint-plugin-plus": "^2.3.0", 69 | "prettier": "^3.2.5", 70 | "@rollup/plugin-commonjs": "^26.0.1", 71 | "@rollup/plugin-image": "^3.0.3", 72 | "@rollup/plugin-node-resolve": "^15.2.3", 73 | "@rollup/plugin-replace": "^5.0.7", 74 | "@rollup/plugin-terser": "^0.4.4", 75 | "@rollup/plugin-typescript": "^11.1.6", 76 | "rollup-plugin-license": "^3.5.2", 77 | "@types/semver": "^7.5.8", 78 | "@types/uuid": "^10.0.0", 79 | "obsidian": "^1.7.2", 80 | "rollup": "^4.24.0", 81 | "semver": "^7.6.3", 82 | "uuid": "^10.0.0", 83 | "all-contributors-cli": "^6.26.1" 84 | } 85 | } 86 | --------------------------------------------------------------------------------