Skip to content

Commit

Permalink
feat: adds Hide Empty Admonitions setting (close #171)
Browse files Browse the repository at this point in the history
  • Loading branch information
valentine195 committed Feb 8, 2022
1 parent fe31ccf commit bf379bf
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 55 deletions.
89 changes: 64 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,56 +571,95 @@ Instructions:

Please note that I can give no guarantees of stability on your publish site. Other JavaScript you include may conflict with this file. If you run into an issue using it, please create an issue on this repository and I will try to help you.

## Settings
# Settings

### Syntax Highlighting
## Custom Admonition Types

Turns on an experimental mode that uses Obsidian's markdown syntax highlighter inside admonition code blocks.
[Custom admonition](#custom-admonitions) types can be created and managed in this section of the settings.

### Sync Links to Metadata Cache
## Admonition Settings

Settings specific to admonitions are managed in this section.

### Add Drop Shadow

A drop shadow will be added to admonitions by default.

If this setting is off, rendered admonitions will receive the `.no-drop` class.

### Collapsible By Default

All admonitions will be collapsible by default, unless `collapse: none` is set in the admonition parameters.

### Default Collapse Type

> :warning: This setting is only available when Collapsible By Default is true.
Set the default collapse type used when setting an admonition collapsible by default.

### Add Copy Button

A "Copy Content" button will be added to the top-right corner of the admonition content.

This will attempt to sync internal links within admonitions to the metadata cache used by Obsidian. This will allow graph view to display these links.
### Parse Titles as Markdown

This setting is experimental and could have unintended consequences. If you begin to experience odd behavior, try turning it off and reloading Obsidian.
Turn this setting off to prevent admonition titles from being rendered as markdown.

### Set Admonition Colors

Controls whether or not a rendered admonition will receive a color.

Turn this off to totally control color via CSS.

### Hide Empty Admonitions

Admonitions with no content are hidden by default.

> :warning: Please note that this only works for Admonitions that have *no text content whatsoever*.
## Additional Syntaxes

### Enable Non-codeblock Admonitions

Allow use of non-codeblock admonitions, described [here](#non-code-block-admonitions).
> :heavy_exclamation_mark: This syntax will be removed in a future version!
>
> It is recommended to use the [Microsoft Document Syntax](#microsoft-document-syntax) instead.
### Generate JS for Publish
Enabled use of `!!! ad-<type>` style admonitions. No longer supported, will be removed in a future version.

This button will export a JavaScript file to be used on a **self-hosted** Obsidian Publish site. The generated JavaScript will only be valid for currently defined Admonition types. Any additional types created after generating the file will require a new file to be generated.
### Allow Microsoft Document Syntax

### Collapsible By Default
Enables use of the [Microsoft Document Syntax](#microsoft-document-syntax) for blockquote admonitions.

### Render Microsoft Document Syntax in Live Preview

Admonitions will be automatically rendered as collapsible (open) by default.
Enables use of the [Microsoft Document Syntax](#microsoft-document-syntax) in live preview.

If set, use `collapse: none` in an admonition block to override.
This feature is still under development and you may experience rendering bugs.

### Default Collapse Type
## Advanced Settings

**This setting is only available if Collapsible By Default is ON**
### Markdown Syntax Highlighting

Admonitions will be automatically rendered as opened or closed when collapsible by default.
Enable syntax highlighting when editing admonition code blocks.

### Copy Button
### Sync Links to Metadata Cache

Adds a "copy content" button to every admonition block.
The plugin will attempt to syncronize links to the metadata cache to be displayed in graph view.

### Register and Unregister Commands
This setting is experimental. Links will only be synced when rendered in an admonition and they will not persist if you close and re-open Obsidian.

Commands may be registered for each custom admonition type to insert them into an open note by clicking the `Register Commands` button.
Please see [this issue](https://github.com/valentine195/obsidian-admonition/issues/144) for more information.

Clicking this button will add two commands for that admonition type:
If you require links to be fully synced, it is recommended to use the [Microsoft Document Syntax](#microsoft-document-syntax).

1. Insert <type>
2. Insert <type> with title
### Generate JS for Publish

These commands can have hotkeys assigned to them under Settings > Hotkeys.
Use this setting to enable Admonitions on custom-domain Obsidian Publish websites.

Registered commands may be removed by clicking on `Unregister Commands`.
See [Publish](#publish) for more information.

## Todo
# Todo

No additional features are planned at this time. If there is a feature missing that you would like to see, please open an issue.

Expand Down
7 changes: 7 additions & 0 deletions src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
box-shadow: 0 0.2rem 0.5rem var(--background-modifier-box-shadow);
}

*:not(.is-live-preview) .admonition.no-content {
display: none;
}
.is-live-preview .admonition.no-content {
opacity: 0.1;
}

.admonition-title {
position: relative;
padding: 0.6rem 0.25em;
Expand Down
45 changes: 33 additions & 12 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import { tokenClassNodeProp } from "@codemirror/stream-parser";
import { Range } from "@codemirror/rangeset";
import { StateEffect, StateField } from "@codemirror/state";

import { Admonition, ISettingsData, AdmonitionIconDefinition } from "./@types";
import {
Admonition,
AdmonitionSettings,
AdmonitionIconDefinition
} from "./@types";
import { getID, getMatches, getParametersFromSource, MSDOCREGEX } from "./util";
import {
ADMONITION_MAP,
Expand Down Expand Up @@ -105,7 +109,7 @@ import { InsertAdmonitionModal } from "./modal";
import "./assets/main.css";
import { isLivePreview, rangesInclude } from "./util/livepreview";

const DEFAULT_APP_SETTINGS: ISettingsData = {
const DEFAULT_APP_SETTINGS: AdmonitionSettings = {
userAdmonitions: {},
syntaxHighlight: false,
copyButton: false,
Expand All @@ -118,12 +122,13 @@ const DEFAULT_APP_SETTINGS: ISettingsData = {
parseTitles: true,
allowMSSyntax: true,
livePreviewMS: true,
dropShadow: true
dropShadow: true,
hideEmpty: false
};

export default class ObsidianAdmonition extends Plugin {
admonitions: { [admonitionType: string]: Admonition } = {};
data: ISettingsData;
data: AdmonitionSettings;

postprocessors: Map<string, MarkdownPostProcessor> = new Map();

Expand Down Expand Up @@ -419,6 +424,12 @@ export default class ObsidianAdmonition extends Plugin {
null
);

if (
(!content.length || contentEl.textContent.trim() == "") &&
this.data.hideEmpty
)
admonition.addClass("no-content");

el.firstElementChild.replaceWith(admonition);
});

Expand Down Expand Up @@ -490,6 +501,11 @@ export default class ObsidianAdmonition extends Plugin {
);

MarkdownRenderer.renderMarkdown(content, contentEl, "", null);
if (
(!content.length || contentEl.textContent.trim() == "") &&
self.data.hideEmpty
)
admonitionElement.addClass("no-content");
return parent;
}
}
Expand Down Expand Up @@ -1078,7 +1094,7 @@ ${editor.getDoc().getSelection()}\n--- admonition\n`
}

if (content && content.length) {
const admonitionContent = this.getAdmonitionContentElement(
const contentEl = this.getAdmonitionContentElement(
type,
admonitionElement,
content
Expand All @@ -1096,7 +1112,7 @@ ${editor.getDoc().getSelection()}\n--- admonition\n`
setImmediate(() => {
MarkdownRenderer.renderMarkdown(
content,
admonitionContent,
contentEl,
sourcePath,
markdownRenderChild
);
Expand All @@ -1110,16 +1126,21 @@ ${editor.getDoc().getSelection()}\n--- admonition\n`
} else {
MarkdownRenderer.renderMarkdown(
content,
admonitionContent,
contentEl,
sourcePath,
markdownRenderChild
);
}

const taskLists =
admonitionContent.querySelectorAll<HTMLInputElement>(
".task-list-item-checkbox"
);
if (
(!content.length || contentEl.textContent.trim() == "") &&
this.data.hideEmpty
)
admonitionElement.addClass("no-content");

const taskLists = contentEl.querySelectorAll<HTMLInputElement>(
".task-list-item-checkbox"
);
if (taskLists?.length) {
const split = src.split("\n");
let slicer = 0;
Expand All @@ -1135,7 +1156,7 @@ ${editor.getDoc().getSelection()}\n--- admonition\n`
}

const links =
admonitionContent.querySelectorAll<HTMLAnchorElement>(
contentEl.querySelectorAll<HTMLAnchorElement>(
"a.internal-link"
);

Expand Down
38 changes: 20 additions & 18 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
Admonition,
AdmonitionIconDefinition,
AdmonitionIconName,
AdmonitionIconType,
ObsidianAdmonitionPlugin
AdmonitionIconType
} from "./@types";

import { getIconNode, getIconType, WARNING_ICON } from "./util";
Expand All @@ -24,6 +23,7 @@ import { IconSuggestionModal } from "./modal";
//@ts-expect-error
import CONTENT from "../publish/publish.admonition.txt";
import { t } from "src/lang/helpers";
import ObsidianAdmonition from "./main";

/** Taken from https://stackoverflow.com/questions/34849001/check-if-css-selector-is-valid/42149818 */
const isSelectorValid = ((dummyElement) => (selector: string) => {
Expand All @@ -36,11 +36,9 @@ const isSelectorValid = ((dummyElement) => (selector: string) => {
})(document.createDocumentFragment());

export default class AdmonitionSetting extends PluginSettingTab {
plugin: ObsidianAdmonitionPlugin;
additionalEl: HTMLDivElement;
constructor(app: App, plugin: ObsidianAdmonitionPlugin) {
constructor(app: App, public plugin: ObsidianAdmonition) {
super(app, plugin);
this.plugin = plugin;
}
async display(): Promise<void> {
this.containerEl.empty();
Expand Down Expand Up @@ -233,6 +231,20 @@ export default class AdmonitionSetting extends PluginSettingTab {
await this.buildTypes();
})
);
new Setting(containerEl)
.setName("Hide Empty Admonitions")
.setDesc(
"Any admonition that does not have content inside it will be hidden."
)
.addToggle((t) =>
t.setValue(this.plugin.data.hideEmpty).onChange(async (v) => {
this.plugin.data.hideEmpty = v;

await this.plugin.saveSettings();

await this.buildTypes();
})
);
}

buildAdvanced(containerEl: HTMLDetailsElement) {
Expand All @@ -242,14 +254,7 @@ export default class AdmonitionSetting extends PluginSettingTab {
summary.createDiv("collapser").createDiv("handle");

new Setting(containerEl)
.setName(
createFragment((e) => {
e.appendChild(WARNING_ICON.cloneNode(true));
e.createSpan({
text: t(" Markdown Syntax Highlighting")
});
})
)
.setName(t("Markdown Syntax Highlighting"))
.setDesc(
t(
"Use Obsidian's markdown syntax highlighter in admonition code blocks. This setting is experimental and could cause errors."
Expand Down Expand Up @@ -301,7 +306,7 @@ export default class AdmonitionSetting extends PluginSettingTab {
f.createSpan({ text: "file." });
f.createEl("br");
f.createEl("strong", {
text: "Please note that this can only be done on self-hosted publish sites."
text: "Please note that this can only be done on custom domain publish sites."
});
})
)
Expand Down Expand Up @@ -528,10 +533,7 @@ class SettingsModal extends Modal {
noTitle: boolean = false;
admonitionPreview: HTMLElement;
copy: boolean;
constructor(
public plugin: ObsidianAdmonitionPlugin,
admonition?: Admonition
) {
constructor(public plugin: ObsidianAdmonition, admonition?: Admonition) {
super(plugin.app);
if (admonition) {
this.color = admonition.color;
Expand Down

0 comments on commit bf379bf

Please sign in to comment.