diff --git a/@types/types.ts b/@types/types.ts index f36d0fe..e6e50d2 100644 --- a/@types/types.ts +++ b/@types/types.ts @@ -10,6 +10,9 @@ export declare class ObsidianAdmonitionPlugin extends Plugin_2 { removeAdmonition: (admonition: Admonition) => Promise; admonitions: { [admonitionType: string]: Admonition }; userAdmonitions: { [admonitionType: string]: Admonition }; + syntaxHighlight: boolean; + turnOnSyntaxHighlighting: (types?: string[]) => void; + turnOffSyntaxHighlighting: (types?: string[]) => void; saveSettings: () => Promise; loadSettings: () => Promise; addAdmonition: (admonition: Admonition) => Promise; diff --git a/README.md b/README.md index cbaf5d6..d962fae 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,11 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. ![](https://raw.githubusercontent.com/valentine195/obsidian-admonition/master/images/title.png) +Custom titles are rendered as Markdown, so they support the full Obsidian Markdown syntax. + +![](https://https://raw.githubusercontent.com/valentine195/obsidian-admonition/master/images/title-markdown.png) +![](https://https://raw.githubusercontent.com/valentine195/obsidian-admonition/master/images/rendered-title-markdown.png) + Leave the title field blank to only display the admonition. ````markdown @@ -72,7 +77,6 @@ If a blank title is provided, the collapse parameter will not do anything. ![](https://raw.githubusercontent.com/valentine195/obsidian-admonition/master/images/collapse.gif) - ## Admonition Types The following admonition types are currently supported: @@ -158,11 +162,11 @@ Every admonition receives the following CSS classes: } ``` -***Please note, as of 3.0.0, the admonition colors are no longer set in the CSS.*** +**_Please note, as of 3.0.0, the admonition colors are no longer set in the CSS._** Each admonition receives the `.admonition-` class. You can use this selector to override specific admonition types, but the plugin does not add any styling using this selector by default. -To set the color of admonition types via CSS, specific the following the `--admonition-color` variable ***as an RGB triad***: +To set the color of admonition types via CSS, specific the following the `--admonition-color` variable **_as an RGB triad_**: ```css .admonition-note { @@ -234,14 +238,21 @@ An icon without a title will have this CSS: # Version History -## 3.1.0 -- Fixed issue where checkboxes in admonitions were not toggleable +## 3.2.0 + +- Added a setting to turn on default Obsidian syntax highlighting to admonition code block types +- Admonitions now render titles as Markdown + +## 3.1.0 + +- Fixed issue where checkboxes in admonitions were not toggleable + ## 3.0.0 -- Added ability to create custom admonitions via Settings - - Color, icon, and admonition-type are customizable - - Default admonitions can be overridden by creating a custom admonition of the same type - - Delete the custom admonition to restore default +- Added ability to create custom admonitions via Settings + - Color, icon, and admonition-type are customizable + - Default admonitions can be overridden by creating a custom admonition of the same type + - Delete the custom admonition to restore default ## 2.0.0 diff --git a/images/rendered-title-markdown.PNG b/images/rendered-title-markdown.PNG new file mode 100644 index 0000000..200d6b8 Binary files /dev/null and b/images/rendered-title-markdown.PNG differ diff --git a/images/title-markdown.PNG b/images/title-markdown.PNG new file mode 100644 index 0000000..28343cb Binary files /dev/null and b/images/title-markdown.PNG differ diff --git a/manifest.json b/manifest.json index a14aaf3..29da3d0 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-admonition", "name": "Admonition", - "version": "3.1.2", + "version": "3.2.0", "minAppVersion": "0.11.0", "description": "Admonition block-styled content for Obsidian.md", "author": "Jeremy Valentine", diff --git a/package.json b/package.json index 64c8751..74f1aeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-admonition", - "version": "3.1.2", + "version": "3.2.0", "description": "Admonition block-styled content for Obsidian.md", "main": "main.js", "scripts": { diff --git a/src/codemirror.js b/src/codemirror.js new file mode 100644 index 0000000..2c9986b --- /dev/null +++ b/src/codemirror.js @@ -0,0 +1 @@ +module.exports = CodeMirror; diff --git a/src/main.css b/src/main.css index da05aab..5a90923 100644 --- a/src/main.css +++ b/src/main.css @@ -3,6 +3,11 @@ --admonition-details-icon: url("data:image/svg+xml;charset=utf-8,"); } +.use-csv-marker > svg { + color: yellow; + margin-right: 8px; +} + .admonition { margin: 1.5625em 0; padding: 0 0.6rem; @@ -24,6 +29,11 @@ background-color: rgba(var(--admonition-color), 0.1); } +.admonition-title p { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + .admonition-title-icon { position: absolute; left: 0.6rem; diff --git a/src/main.ts b/src/main.ts index 8a48cb9..049b3b6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,8 @@ import { import { Admonition, ObsidianAdmonitionPlugin } from "../@types/types"; import { findIconDefinition, icon } from "./icons"; +import * as CodeMirror from "./codemirror"; + Object.fromEntries = Object.fromEntries || /** Polyfill taken from https://github.com/tc39/proposal-object-from-entries/blob/master/polyfill.js */ @@ -37,6 +39,10 @@ Object.fromEntries = return obj; }; +/* const compareVersions = (a: string, b: string) => { + return a.localeCompare(b, undefined, { numeric: true }) === 1; +}; */ + import "./main.css"; import AdmonitionSetting from "./settings"; @@ -92,16 +98,33 @@ export default class ObsidianAdmonition implements ObsidianAdmonitionPlugin { admonitions: { [admonitionType: string]: Admonition } = {}; userAdmonitions: { [admonitionType: string]: Admonition } = {}; + syntaxHighlight: boolean; async saveSettings() { - await this.saveData(this.userAdmonitions); + await this.saveData({ + syntaxHighlight: this.syntaxHighlight || false, + userAdmonitions: this.userAdmonitions || {}, + version: this.manifest.version + }); } async loadSettings() { - this.userAdmonitions = await this.loadData(); + let data = Object.assign({}, await this.loadData()); + + if (!Object.prototype.hasOwnProperty.call(data, "syntaxHighlight")) { + data = { + userAdmonitions: data, + syntaxHighlight: false + }; + } + + let { userAdmonitions = {}, syntaxHighlight = false } = data || {}; + this.userAdmonitions = userAdmonitions; + this.syntaxHighlight = syntaxHighlight; this.admonitions = { ...ADMONITION_MAP, ...this.userAdmonitions }; + await this.saveSettings(); } async addAdmonition(admonition: Admonition): Promise { this.userAdmonitions = { @@ -116,6 +139,9 @@ export default class ObsidianAdmonition `ad-${admonition.type}`, this.postprocessor.bind(this, admonition.type) ); + if (this.syntaxHighlight) { + this.turnOnSyntaxHighlighting([admonition.type]); + } await this.saveSettings(); } @@ -127,6 +153,11 @@ export default class ObsidianAdmonition ...ADMONITION_MAP, ...this.userAdmonitions }; + + if (this.syntaxHighlight) { + this.turnOffSyntaxHighlighting([admonition.type]); + } + await this.saveSettings(); } async onload(): Promise { @@ -136,11 +167,53 @@ export default class ObsidianAdmonition this.addSettingTab(new AdmonitionSetting(this.app, this)); - Object.keys(this.admonitions).forEach((type) => + Object.keys(this.admonitions).forEach((type) => { this.registerMarkdownCodeBlockProcessor( `ad-${type}`, this.postprocessor.bind(this, type) - ) + ); + }); + if (this.syntaxHighlight) { + this.turnOnSyntaxHighlighting(); + } + } + turnOnSyntaxHighlighting(types: string[] = Object.keys(this.admonitions)) { + if (!this.syntaxHighlight) return; + types.forEach((type) => { + if (this.syntaxHighlight) { + /** Process from @deathau's syntax highlight plugin */ + CodeMirror.defineMode(`ad-${type}`, (config, options) => { + return CodeMirror.getMode(config, "hypermd"); + }); + } + }); + + this.app.workspace.layoutReady + ? this.layoutReady() + : this.app.workspace.on("layout-ready", this.layoutReady); + } + + turnOffSyntaxHighlighting(types: string[] = Object.keys(this.admonitions)) { + types.forEach((type) => { + if (CodeMirror.modes.hasOwnProperty(`ad-${type}`)) { + delete CodeMirror.modes[`ad-${type}`]; + } + }); + this.app.workspace.layoutReady + ? this.layoutReady() + : this.app.workspace.on("layout-ready", this.layoutReady); + } + + layoutReady() { + // don't need the event handler anymore, get rid of it + this.app.workspace.off("layout-ready", this.layoutReady); + this.refreshLeaves(); + } + + refreshLeaves() { + // re-set the editor mode to refresh the syntax highlighting + this.app.workspace.iterateCodeMirrors((cm) => + cm.setOption("mode", cm.getOption("mode")) ); } postprocessor( @@ -337,10 +410,16 @@ export default class ObsidianAdmonition iconName: this.admonitions[type].icon }) ).html[0]; - titleEl.createSpan({ text: title }); + + let titleContentEl = createDiv(); + MarkdownRenderer.renderMarkdown(title, titleContentEl, "", null); + + titleEl.appendChild(titleContentEl); return admonition; } async onunload() { console.log("Obsidian Admonition unloaded"); + + this.turnOffSyntaxHighlighting(); } } diff --git a/src/settings.ts b/src/settings.ts index 11f8756..4c483de 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -24,6 +24,36 @@ export default class AdmonitionSetting extends PluginSettingTab { containerEl.createEl("h2", { text: "Admonition Settings" }); + let syntax = new Setting(containerEl); + syntax.setDesc( + "Use Obsidian's markdown syntax highlighter in admonition code blocks. This setting is experimental and could cause errors." + ); + let name = syntax.nameEl.createDiv({ + cls: "use-csv-marker" + }); + name.appendChild( + icon( + findIconDefinition({ + iconName: "exclamation-triangle", + prefix: "fas" + }) + ).node[0] + ); + name.appendChild(createSpan({ text: "Markdown Syntax Highlighting" })); + + syntax.addToggle((t) => { + t.setValue(this.plugin.syntaxHighlight); + t.onChange(async (v) => { + this.plugin.syntaxHighlight = v; + if (v) { + this.plugin.turnOnSyntaxHighlighting(); + } else { + this.plugin.turnOffSyntaxHighlighting(); + } + await this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName("Add New") .setDesc("Add a new Admonition type.") diff --git a/versions.json b/versions.json index 379f85d..faf7a08 100644 --- a/versions.json +++ b/versions.json @@ -2,5 +2,6 @@ "0.2.3": "0.11.0", "1.0.1": "0.11.0", "2.0.1": "0.11.0", - "3.1.2": "0.11.0" + "3.1.2": "0.11.0", + "3.2.0": "0.11.0" }