feat(links): added ofm option to style unresolved or broken links differently (#1992)
* feat: add option to disable broken wikilinks
* fix(style): update hover color for broken links and introduce new class
* feat: add "disableBrokenWikilinks" option to ObsidianFlavoredMarkdown
| | |
| | | - `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax. |
| | | - `enableVideoEmbed`: If `true` (default), enables the embedding of video files. |
| | | - `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`. |
| | | - `disableBrokenWikilinks`: If `true`, replaces links to non-existent notes with a dimmed, disabled link. Defaults to `false`. |
| | | |
| | | > [!warning] |
| | | > Don't remove this plugin if you're using [[Obsidian compatibility|Obsidian]] to author the content! |
| | |
| | | enableYouTubeEmbed: boolean |
| | | enableVideoEmbed: boolean |
| | | enableCheckbox: boolean |
| | | disableBrokenWikilinks: boolean |
| | | } |
| | | |
| | | const defaultOptions: Options = { |
| | |
| | | enableYouTubeEmbed: true, |
| | | enableVideoEmbed: true, |
| | | enableCheckbox: false, |
| | | disableBrokenWikilinks: false, |
| | | } |
| | | |
| | | const calloutMapping = { |
| | |
| | | |
| | | return src |
| | | }, |
| | | markdownPlugins(_ctx) { |
| | | markdownPlugins(ctx) { |
| | | const plugins: PluggableList = [] |
| | | |
| | | // regex replacements |
| | |
| | | // otherwise, fall through to regular link |
| | | } |
| | | |
| | | // treat as broken link if slug not in ctx.allSlugs |
| | | if (opts.disableBrokenWikilinks) { |
| | | const slug = slugifyFilePath(fp as FilePath) |
| | | const exists = ctx.allSlugs && ctx.allSlugs.includes(slug) |
| | | if (!exists) { |
| | | return { |
| | | type: "html", |
| | | value: `<a class=\"internal broken\">${alias ?? fp}</a>`, |
| | | } |
| | | } |
| | | } |
| | | |
| | | // internal link |
| | | const url = fp + anchor |
| | | |
| | |
| | | color: var(--secondary); |
| | | |
| | | &:hover { |
| | | color: var(--tertiary) !important; |
| | | color: var(--tertiary); |
| | | } |
| | | |
| | | &.internal { |
| | |
| | | border-radius: 5px; |
| | | line-height: 1.4rem; |
| | | |
| | | &.broken { |
| | | color: var(--secondary); |
| | | opacity: 0.5; |
| | | transition: opacity 0.2s ease; |
| | | &:hover { |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | | |
| | | &:has(> img) { |
| | | background-color: transparent; |
| | | border-radius: 0; |