Compare commits

..

24 commits

Author SHA1 Message Date
@gapmiss
dba673239f chore: release 1.1.12 2026-06-14 11:26:33 -05:00
@gapmiss
bac3097ff7 fix: update tsconfig, esbuild, and release script
Remove unnecessary baseUrl, use Bundler moduleResolution, fix
indentation in tsconfig. Bump esbuild to 0.28.1. Read minAppVersion
from manifest.json in release script instead of hardcoding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-14 11:25:57 -05:00
@gapmiss
3ca85bcb36 fix: upgrade esbuild to ^0.28.0 to resolve security vulnerability
Addresses moderate severity CVE in esbuild <=0.24.2 (GHSA-67mh-4wv8-2f99).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-06-06 15:13:49 -05:00
@gapmiss
2f74e72b09 chore: release 1.1.11 2026-06-04 17:08:18 -05:00
@gapmiss
87bc426287 fix: remove unused _currentLine variable 2026-06-04 17:08:08 -05:00
@gapmiss
ba3cf74ed7 chore: release 1.1.10 2026-06-04 16:46:25 -05:00
gapmiss
735dba14c4
Merge pull request #18 from Niv20/Fix-RTL
Fix: use logical padding for badge text to fix RTL spacing
2026-06-04 16:44:37 -05:00
Niv Leibovich
c68f50f7e0
Fix: use logical padding for badge text to fix RTL spacing
Replace `padding-right` with `padding-inline-end` on badge title and GitHub label. 

Fixes text hugging the edge in RTL languages, like Hebrew.

No visual change for LTR.
2026-06-05 00:34:32 +03:00
@gapmiss
b7c28eacd4 docs: update README.md 2026-06-02 17:07:51 -05:00
@gapmiss
a6bbf8c3a3 docs: update README.md 2026-06-02 17:06:51 -05:00
@gapmiss
6ac5a55f14 docs: update README.md 2026-06-02 17:01:09 -05:00
@gapmiss
9d6f147873 docs: update README.md 2026-06-02 16:59:51 -05:00
@gapmiss
1967a33a72 docs: update README.md 2026-06-02 16:55:55 -05:00
@gapmiss
e5531fe347 chore: release 1.1.9 2026-05-31 14:16:19 -05:00
@gapmiss
1969494fc8 docs: add CONTRIBUTING guide 2026-05-31 14:16:04 -05:00
@gapmiss
4497951721 chore: release 1.1.8 2026-05-29 18:19:39 -05:00
@gapmiss
ba118a7681 Replace :has() selectors with badge-link class for performance
The :has() selector causes broad selector invalidation on every DOM
change. Using a direct class applied during badge creation is more
performant and avoids community scanner warnings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-29 18:19:27 -05:00
@gapmiss
6d0c71ec73 chore: release 1.1.7 2026-05-29 17:47:42 -05:00
@gapmiss
02c82a339e Add link support for badges using >> syntax
Badges can now include clickable links with `[!!type:text>>link]` syntax.
Supports both wikilinks (`[[Note]]`) and external URLs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-29 17:47:22 -05:00
@gapmiss
f672e3492e Document data-badge-type CSS attribute for plain-text badges
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-29 17:19:19 -05:00
@gapmiss
1bd093dec5 chore: release 1.1.6 2026-05-29 17:14:31 -05:00
@gapmiss
c577b35de7 Add data-badge-type attribute to plain-text badges
Enables CSS targeting of specific badge types via data attribute.
Example: .inline-badge-extra[data-badge-type="Path"] { ... }

Closes #16

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-29 17:14:14 -05:00
@gapmiss
88ab8604fc Clarify icon name requirements for custom syntax
Documents that custom syntax requires actual Lucide icon names,
while standard syntax supports both built-in aliases and Lucide names.

Closes #11

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-26 17:22:58 -05:00
@gapmiss
df755b9259 Document custom badge KEY behavior and workaround
Clarifies that KEY is for aria-label only, not displayed visually.
Shows workaround for displaying a label in the VAL text.

Addresses #12

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-26 17:16:39 -05:00
11 changed files with 378 additions and 191 deletions

2
.gitignore vendored
View file

@ -21,5 +21,5 @@ data.json
# Exclude macOS Finder (System Explorer) View States
.DS_Store
.hotreload
.claude
CLAUDE.md

24
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,24 @@
# Contributing
Thanks for your interest in contributing!
## Bug reports
Open an issue with steps to reproduce and expected vs actual behavior.
## Pull requests
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run `npm run build` and `npx eslint .` to verify
5. Test in Obsidian
6. Submit a PR with a clear description
## Development
```bash
npm install
npm run dev # Watch mode
npm run build # Production build
```

143
README.md
View file

@ -2,23 +2,36 @@
### Introduction
A light-weight plugin for displaying inline "badges" in [Obsidian.md](https://github.com/obsidianmd) which acts similarly to a key-value store(database) for querying via default search or [Dataview](https://github.com/blacksmithgu/obsidian-dataview) plugin.
A light-weight plugin for displaying inline "badges" in [Obsidian.md](https://github.com/obsidianmd).
- [Usage](#usage)
- [Github styled badges](#Github)
- [Plain-text](#Plain-text)
- [custom](#custom)
- [Usage in tables](#usage-in-tables)
- [Installation](#Installation)
- [CSS styles](#CSS)
- [Dataview plugin](#Dataview)
- [Development](#Development)
- [Notes](#Notes)
### Installation
[Install from community.obsidian.md](https://community.obsidian.md/plugins/badges)
From Obsidian's settings or preferences:
1. Community Plugins > Browse
2. Search for "Badges"
Manually:
1. download the latest [release](https://github.com/gapmiss/badges/releases/latest) archive
2. uncompress the downloaded archive
3. move the `badges` folder to `/path/to/vault/.obsidian/plugins/`
4. Settings > Community plugins > reload **Installed plugins**
5. enable plugin
or:
1. download `main.js`, `manifest.json` & `styles.css` from the latest [release](https://github.com/gapmiss/badges/releases/latest)
2. create a new folder `/path/to/vault/.obsidian/plugins/badges`
3. move all 3 files to `/path/to/vault/.obsidian/plugins/badges`
4. Settings > Community plugins > reload **Installed plugins**
5. enable plugin
### Usage
###### default syntax
#### default syntax
```markdown
`[!!KEY:VAL]`
@ -29,7 +42,7 @@ A light-weight plugin for displaying inline "badges" in [Obsidian.md](https://gi
| `KEY` | the type and name of the `ICON` |
| `VAL` | the value and text displayed |
###### shorthand syntax
#### shorthand syntax
For built-in badge types, you can omit the value and colon:
@ -113,9 +126,9 @@ For example, `[!!success]` displays as "Success" with a checkmark icon. This wor
![](assets/Badges-demo-Obsidian-v1.3.7-20230709171053.png)
### Plain-text
#### Plain-text
###### syntax
##### syntax
```markdown
`[!!|KEY:VAL]`
@ -138,9 +151,9 @@ For example, `[!!success]` displays as "Success" with a checkmark icon. This wor
![](assets/Badges-demo-Obsidian-v1.3.7-20230709171713.png)
### custom
#### custom
###### syntax
##### syntax
```markdown
`[!!|ICON|KEY:VAL|COLOR-RGB]`
@ -149,12 +162,25 @@ For example, `[!!success]` displays as "Success" with a checkmark icon. This wor
| syntax | details |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| <code>\|</code> | start pipe symbol |
| `ICON` | name of icon. e.g. `lucide-dice` |
| `ICON` | [Lucide icon](https://lucide.dev/icons/) name. e.g. `dice` or `lucide-dice` |
| <code>\|</code> | pipe symbol |
| `KEY:VAL` | `KEY` is the type or label, `VAL` is the value text displayed. e.g. `release:1.0.0` |
| <code>\|</code> | pipe symbol |
| `COLOR-RGB` <br>(optional, defaults to currentColor) | 3 (R.G.B.) numeric (0-255) values, separated by commas. e.g. `144,144,144` or CSS variable e.g. `var(--color-red-rgb)` |
> [!NOTE]
> The `KEY` is used for the aria-label (accessibility) and is not displayed visually. Only the `VAL` text is shown. To display a label, include it in the `VAL`:
> ```markdown
> `[!!|tag|release:Release 1.2.1]`
> ```
> or simply:
> ```markdown
> `[!!|tag|:Release 1.2.1]`
> ```
> [!IMPORTANT]
> Custom syntax requires actual [Lucide icon](https://lucide.dev/icons/) names (e.g., `pen-tool`, `message-square`). The built-in aliases like `notice` or `success` only work with standard syntax. For example, use `[!!|pen-tool|notice:text|color]` not `[!!|notice|notice:text|color]`.
###### example
```markdown
@ -177,11 +203,37 @@ For example, `[!!success]` displays as "Success" with a checkmark icon. This wor
![](assets/Badges-demo-Obsidian-v1.3.7-20230709171541.png)
![](assets/Badges-demo-Obsidian-v1.3.7-20230709171534.png)
### Usage in tables
#### Links
Badges can be made clickable by adding a link using the `>>` syntax.
##### syntax
```markdown
`[!!KEY:VAL>>LINK]`
```
| syntax | details |
| ------ | ------- |
| `>>` | link delimiter |
| `LINK` | wikilink `[[Note]]` or external URL `https://...` |
###### examples
```markdown
`[!!info:Documentation>>https://obsidian.md]`
`[!!note:See also>>[[My Note]]]`
`[!!tip:Jump to section>>[[My Note#Heading]]]`
```
> [!NOTE]
> Links work with all badge types including custom badges.
#### Usage in tables
When using badges inside Markdown tables, the `|` pipe character conflicts with the table cell separator. To work around this, use escaped pipes `\|` instead of `|` in your badge syntax.
###### syntax
##### syntax
```markdown
`[!!\|ICON\|KEY:VAL\|COLOR-RGB]`
@ -199,40 +251,13 @@ When using badges inside Markdown tables, the `|` pipe character conflicts with
> [!NOTE]
> Badges without pipes (e.g. `[!!success:Done]`) work in tables without any changes.
### Installation
From Obsidian's settings or preferences:
1. [Open in Obsidian.md](obsidian://show-plugin?id=badges)
or:
1. Community Plugins > Browse
2. Search for "Badges"
Manually:
1. download the latest [release archive](https://github.com/gapmiss/badges/releases/download/1.1.0/badges-v1.1.0.zip)
2. uncompress the downloaded archive
3. move the `badges` folder to `/path/to/vault/.obsidian/plugins/`
4. Settings > Community plugins > reload **Installed plugins**
5. enable plugin
or:
1. download `main.js`, `manifest.json` & `styles.css`
2. create a new folder `/path/to/vault/.obsidian/plugins/badges`
3. move all 3 files to `/path/to/vault/.obsidian/plugins/badges`
4. Settings > Community plugins > reload **Installed plugins**
5. enable plugin
### CSS
Custom `CSS` styles can be applied via CSS snippets. All colors and styles can be over-written just the same.
See [CSS snippets - Obsidian Help](https://help.obsidian.md/Extending+Obsidian/CSS+snippets)
##### variables
#### variables
```css
body {
@ -251,8 +276,30 @@ body {
}
```
#### Styling plain-text badges by type
Plain-text badges include a `data-badge-type` attribute containing the `KEY` value, enabling CSS targeting of specific badge types.
###### examples
```css
/* Style all "Status" badges */
.inline-badge-extra[data-badge-type="Status"] {
background-color: rgba(var(--color-green-rgb), .22);
color: rgba(var(--color-green-rgb), .88);
}
/* Style "Priority" badges differently */
.inline-badge-extra[data-badge-type="Priority"] {
background-color: rgba(var(--color-red-rgb), .22);
color: rgba(var(--color-red-rgb), .88);
}
```
### Dataview
Badges can act similarly to a key-value store(database) for querying via default search or [Dataview](https://github.com/blacksmithgu/obsidian-dataview) plugin.
View and copy example dataview queries: [badges-dataview](assets/badges-dataview.md)
### Development

View file

@ -1,7 +1,7 @@
{
"id": "badges",
"name": "Badges",
"version": "1.1.5",
"version": "1.1.12",
"minAppVersion": "0.15.0",
"description": "Add inline badges/callouts to notes.",
"author": "@gapmiss",

306
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "badges",
"version": "1.1.0",
"version": "1.1.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "badges",
"version": "1.1.0",
"version": "1.1.11",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.0.0",
@ -15,7 +15,7 @@
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/parser": "^8.59.4",
"esbuild": "0.17.3",
"esbuild": "^0.28.1",
"eslint": "^9.39.4",
"eslint-plugin-obsidianmd": "^0.3.0",
"obsidian": "latest",
@ -45,10 +45,27 @@
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
"integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz",
"integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
"integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
@ -59,13 +76,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz",
"integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
"integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
@ -76,13 +93,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz",
"integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
"integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
@ -93,13 +110,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz",
"integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
"integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@ -110,13 +127,13 @@
"darwin"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz",
"integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
"integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
@ -127,13 +144,13 @@
"darwin"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz",
"integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
"integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
@ -144,13 +161,13 @@
"freebsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz",
"integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
"integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
@ -161,13 +178,13 @@
"freebsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz",
"integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
"integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
@ -178,13 +195,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz",
"integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
"integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
@ -195,13 +212,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz",
"integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
"integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
@ -212,13 +229,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz",
"integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
"integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
@ -229,13 +246,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz",
"integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
"integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
@ -246,13 +263,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz",
"integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
"integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
@ -263,13 +280,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz",
"integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
"integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
@ -280,13 +297,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz",
"integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
"integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
@ -297,13 +314,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz",
"integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
"integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
@ -314,13 +331,30 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
"integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz",
"integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
"integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
@ -331,13 +365,30 @@
"netbsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
"integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz",
"integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
"integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
@ -348,13 +399,30 @@
"openbsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
"integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz",
"integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
"integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
@ -365,13 +433,13 @@
"sunos"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz",
"integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
"integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
@ -382,13 +450,13 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz",
"integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
"integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
@ -399,13 +467,13 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz",
"integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
"integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
@ -416,7 +484,7 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@eslint-community/eslint-utils": {
@ -1812,9 +1880,9 @@
}
},
"node_modules/esbuild": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz",
"integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==",
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@ -1822,31 +1890,35 @@
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.17.3",
"@esbuild/android-arm64": "0.17.3",
"@esbuild/android-x64": "0.17.3",
"@esbuild/darwin-arm64": "0.17.3",
"@esbuild/darwin-x64": "0.17.3",
"@esbuild/freebsd-arm64": "0.17.3",
"@esbuild/freebsd-x64": "0.17.3",
"@esbuild/linux-arm": "0.17.3",
"@esbuild/linux-arm64": "0.17.3",
"@esbuild/linux-ia32": "0.17.3",
"@esbuild/linux-loong64": "0.17.3",
"@esbuild/linux-mips64el": "0.17.3",
"@esbuild/linux-ppc64": "0.17.3",
"@esbuild/linux-riscv64": "0.17.3",
"@esbuild/linux-s390x": "0.17.3",
"@esbuild/linux-x64": "0.17.3",
"@esbuild/netbsd-x64": "0.17.3",
"@esbuild/openbsd-x64": "0.17.3",
"@esbuild/sunos-x64": "0.17.3",
"@esbuild/win32-arm64": "0.17.3",
"@esbuild/win32-ia32": "0.17.3",
"@esbuild/win32-x64": "0.17.3"
"@esbuild/aix-ppc64": "0.28.1",
"@esbuild/android-arm": "0.28.1",
"@esbuild/android-arm64": "0.28.1",
"@esbuild/android-x64": "0.28.1",
"@esbuild/darwin-arm64": "0.28.1",
"@esbuild/darwin-x64": "0.28.1",
"@esbuild/freebsd-arm64": "0.28.1",
"@esbuild/freebsd-x64": "0.28.1",
"@esbuild/linux-arm": "0.28.1",
"@esbuild/linux-arm64": "0.28.1",
"@esbuild/linux-ia32": "0.28.1",
"@esbuild/linux-loong64": "0.28.1",
"@esbuild/linux-mips64el": "0.28.1",
"@esbuild/linux-ppc64": "0.28.1",
"@esbuild/linux-riscv64": "0.28.1",
"@esbuild/linux-s390x": "0.28.1",
"@esbuild/linux-x64": "0.28.1",
"@esbuild/netbsd-arm64": "0.28.1",
"@esbuild/netbsd-x64": "0.28.1",
"@esbuild/openbsd-arm64": "0.28.1",
"@esbuild/openbsd-x64": "0.28.1",
"@esbuild/openharmony-arm64": "0.28.1",
"@esbuild/sunos-x64": "0.28.1",
"@esbuild/win32-arm64": "0.28.1",
"@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/escape-string-regexp": {

View file

@ -1,6 +1,6 @@
{
"name": "badges",
"version": "1.1.5",
"version": "1.1.12",
"description": "Badges for Obsidian (https://obsidian.md)",
"main": "main.js",
"scripts": {
@ -17,7 +17,7 @@
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/parser": "^8.59.4",
"esbuild": "0.17.3",
"esbuild": "^0.28.1",
"eslint": "^9.39.4",
"eslint-plugin-obsidianmd": "^0.3.0",
"obsidian": "latest",
@ -28,5 +28,8 @@
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0"
},
"allowScripts": {
"esbuild@0.28.1": true
}
}

View file

@ -23,7 +23,7 @@ const VERSION_TYPES = {
// Default settings
const DEFAULT_VERSION_TYPE = VERSION_TYPES.PATCH;
const RELEASE_FILES = ['main.js', 'manifest.json', 'styles.css'];
const MIN_APP_VERSION = "0.15.0"
const MIN_APP_VERSION = JSON.parse(readFileSync(path.resolve(process.cwd(), 'manifest.json'), 'utf8')).minAppVersion;
// Store original versions for rollback if needed
let originalPackageVersion = '';

View file

@ -3,7 +3,7 @@ import { RangeSetBuilder } from "@codemirror/state"
import { ViewPlugin, WidgetType, EditorView, ViewUpdate, Decoration, DecorationSet } from '@codemirror/view'
import { BADGE_TYPES } from './constants';
const REGEXP = /(`\[!!([^\]]*)\]`)/gm;
const REGEXP = /(`\[!!(.*?)\]`)/gm;
const TAGS = 'code'
export default class BadgesPlugin extends Plugin {
@ -96,17 +96,6 @@ const viewPlugin = ViewPlugin.fromClass(class {
for (let n of lines) {
const line = view.state.doc.line(n);
const startOfLine = line.from;
const endOfLine = line.to;
let _currentLine = false;
currentSelections.forEach((r) => {
if (r.to >= startOfLine && r.from <= endOfLine) {
_currentLine = true;
return;
}
});
let matches = Array.from(line.text.matchAll(REGEXP))
for (const match of matches) {
let add = true
@ -131,7 +120,7 @@ const viewPlugin = ViewPlugin.fromClass(class {
decorations: (v) => v.decorations,
})
function buildBadge(text: string): HTMLSpanElement {
function buildBadge(text: string): HTMLSpanElement | HTMLAnchorElement {
const newEl = createSpan();
const iconEl = createSpan();
const titleEl = createSpan();
@ -139,11 +128,25 @@ function buildBadge(text: string): HTMLSpanElement {
let attrType = "";
const part = text.substring(2);
// Support escaped pipes (\|) for use inside Markdown tables
const content = part.substring(part.length-1,1).trim().replace(/\\\|/g, '|');
let content = part.substring(part.length-1,1).trim().replace(/\\\|/g, '|');
if (!content.length) {
newEl.setText("Badges syntax error");
return newEl;
}
// Parse optional link syntax: >>[[wikilink]] or >>https://...
let linkTarget: string | null = null;
let isWikilink = false;
const linkMatch = content.match(/>>(\[\[.+?\]\]|.+)$/);
if (linkMatch) {
const rawLink = linkMatch[1].trim();
if (rawLink.startsWith('[[') && rawLink.endsWith(']]')) {
linkTarget = rawLink.slice(2, -2);
isWikilink = true;
} else {
linkTarget = rawLink;
}
content = content.slice(0, content.lastIndexOf('>>')).trim();
}
const parts = content.split(':');
let badgeType = parts[0].trim();
let badgeContent: string;
@ -198,7 +201,9 @@ function buildBadge(text: string): HTMLSpanElement {
badgeType = (extras[1].startsWith('ghb>')) ? 'github' : 'github-success';
} else {
iconEl.addClass("inline-badge-extra");
iconEl.setText(badgeType.split("|")[1].trim());
const badgeTypeText = badgeType.split("|")[1].trim();
iconEl.setText(badgeTypeText);
iconEl.dataset.badgeType = badgeTypeText;
attrType = 'text';
badgeType = 'text';
}
@ -223,5 +228,25 @@ function buildBadge(text: string): HTMLSpanElement {
}
newEl.appendChild(titleEl);
}
// Wrap in anchor if link was specified
if (linkTarget) {
const anchor = createEl('a');
anchor.addClass('badge-link');
if (isWikilink) {
anchor.addClass('internal-link');
anchor.setAttr('data-href', linkTarget);
anchor.setAttr('href', linkTarget);
anchor.setAttr('data-tooltip-position', 'top');
} else {
anchor.addClass('external-link');
anchor.setAttr('href', linkTarget);
anchor.setAttr('target', '_blank');
anchor.setAttr('rel', 'noopener');
anchor.setAttr('aria-label', linkTarget);
anchor.setAttr('data-tooltip-position', 'top');
}
anchor.appendChild(newEl);
return anchor;
}
return newEl;
}

View file

@ -21,7 +21,7 @@ body {
.inline-badge .gh-type {
display: inline-block;
font-size: var(--inline-badge-font-size);
padding-right: .5em;
padding-inline-end: .5em;
padding-top: .15em;
}
.inline-badge .inline-badge-extra {
@ -46,7 +46,7 @@ body {
display: inline-block;
font-size: var(--inline-badge-font-size);
font-weight: inherit;
padding-right: 5px;
padding-inline-end: 5px;
padding-top: 2px;
}
.inline-badge[data-inline-badge="info"],
@ -416,3 +416,13 @@ body {
color: rgba(var(--badge-color), 1);
background-color: rgba(var(--badge-color),.123);
}
.badge-link {
text-decoration: none;
}
.badge-link,
.badge-link .inline-badge {
cursor: pointer;
}
.badge-link:hover .inline-badge {
filter: brightness(1.1);
}

View file

@ -1,17 +1,16 @@
{
"compilerOptions": {
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node",
"moduleResolution": "Bundler",
"importHelpers": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"strictNullChecks": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES2020"

View file

@ -5,5 +5,12 @@
"1.1.2": "0.15.0",
"1.1.3": "0.15.0",
"1.1.4": "0.15.0",
"1.1.5": "0.15.0"
"1.1.5": "0.15.0",
"1.1.6": "0.15.0",
"1.1.7": "0.15.0",
"1.1.8": "0.15.0",
"1.1.9": "0.15.0",
"1.1.10": "0.15.0",
"1.1.11": "0.15.0",
"1.1.12": "0.15.0"
}