Skip to content
This repository has been archived by the owner on Oct 30, 2023. It is now read-only.

Commit

Permalink
Implement safety feature for other extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
dbarenholz committed Aug 13, 2022
1 parent 12ef563 commit 3795b4c
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 116 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# Plaintext for Obsidian

This is an [Obisidan](https://obsidian.md) plugin that allows you to open _any_ file as plaintext. It has been developed for Obsidian **v0.13.14**, and tested on **Windows**.
This is an [Obisidan](https://obsidian.md) plugin that allows you to open _any_ file as plaintext.
It has been developed for Obsidian **v0.13.14**, and tested on **Windows**.

Honestly, as long as you can run any Obsidian version you can _probably_ run this plugin as well. The only requirements are that we can register extensions (this existed in v0.12.12 for instance), and that the `viewRegistry` exists, which I'm assuming has been there since the beginning of Obsidian. But, this is all speculation!
Honestly, as long as you can run any Obsidian version you can _probably_ run this plugin as well.
The only requirements are that we can register extensions (this existed in v0.12.12 for instance), and that the `viewRegistry` exists, which I'm assuming has been there since the beginning of Obsidian.
But, this is all speculation!

**NOTE: There are other plugins that allow you to edit specific files. MAKE SURE TO NOT TYPE THEIR EXTENSIONS INTO THE SETTINGS FIELD FOR THIS PLUGIN. I cannot (yet) check for specific plugins that have their own view for a particular extension, and as such this plugin WILL overwrite the view, and break the other extension. If you do this by accident, open the plugin folder (`.obsidian/plugins/obsidian-plaintext/`), and remove from the `data.json` file the extensions that you typed by mistake.**
## Usage

Type your desired file formats into the extensions text field in the settings, then click outside of the text field and watch the magic happen.
Since 0.2.0 by default you can no longer accidentally break other plugins with views. Of course, if you desire, they will be breakable.

**For any version BEFORE 0.2.0: There are other plugins that allow you to edit specific files. MAKE SURE TO NOT TYPE THEIR EXTENSIONS INTO THE SETTINGS FIELD FOR THIS PLUGIN. I cannot (yet) check for specific plugins that have their own view for a particular extension, and as such this plugin WILL overwrite the view, and break the other extension. If you do this by accident, open the plugin folder (`.obsidian/plugins/obsidian-plaintext/`), and remove from the `data.json` file the extensions that you typed by mistake.**~~

## Installing

Interested in editing files in Obsidian? Great. Grab the latest release from the [releases](#) page, and copy `main.js` and `manifest.json` to `.obsidian/plugins/obsidian-plaintext/`. That's it!
Interested in editing files in Obsidian? Great.
Grab the latest release from the [releases](#) page, and copy `main.js` and `manifest.json` to `.obsidian/plugins/obsidian-plaintext/`. That's it!

When approved, you can also install this through Obsidian by searching for **plaintext**.
You can also install the plugin through Obsidian by searching for **plaintext**.

## Roadmap

Expand All @@ -29,6 +38,7 @@ This is free. Keep your money, I don't want it.
**Version 0.2.0 (current)**:

- Long overdue: plugin is enabled for mobile!
- Extra protection: by default, extensions that other plugins add (such as .csv) are not allowed anymore!
- We have over 500 downloads!

**Version 0.1.0**:
Expand Down
68 changes: 62 additions & 6 deletions src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Extensions obsidian supports natively.
* Taken from the help page: https://help.obsidian.md/Advanced+topics/Accepted+file+formats
*
* @version 0.1.0
* @version 0.2.0
* @author dbarenholz
* @since 2021/12/26
* @since 2022/08/13
*/
export const obsidianExts: Set<string> = new Set([
"md",
Expand All @@ -24,26 +24,82 @@ export const obsidianExts: Set<string> = new Set([
"mp4",
"webm",
"ogv",
"mov",
"mkv",
"pdf",
]);

/**
* Takes in a list of extensions, and removes extensions if they are present in the obsidianExts set.
*
* @param exts extensions to process
* @param exts extensions to process.
* @returns All extensions in exts, except if they're present in obsidianExts.
*/
export const removeObsidianExtensions = (exts: string[]): string[] => {
return exts.filter(ext => !obsidianExts.has(ext));
return exts.filter(ext => !obsidianExts.has(ext))
}

/**
* Maps pluginIds to extensions that they use.
* These extensions will be filtered out by default.
*
* @version 0.2.0
* @author dbarenholz
* @since 2022/08/13
*/
export const otherExts: Map<string, string> = new Map([
// https://github.com/deathau/cooklang-obsidian
["cooklang-obsidian", "cook"],
// https://github.com/deathau/csv-obsidian
["csv-obsidian", "csv"],
// https://github.com/caronchen/obsidian-chartsview-plugin
["obsidian-chartsview-plugin", "csv"],
// https://github.com/Darakah/obsidian-fountain
["obsidian-fountain", "fountain"],
// https://github.com/deathau/ini-obsidian
["ini-obsidian", "ini"],
// https://github.com/deathau/txt-as-md-obsidian
["txt-as-md-obsidian", "txt"],
// https://github.com/mkozhukharenko/mdx-as-md-obsidian
["mdx-as-md-obsidian", "mdx"],
// https://github.com/ryanpcmcquen/obsidian-org-mode
["obsidian-org-mode", "org"],
// https://github.com/tgrosinger/ledger-obsidian
["ledger-obsidian", "ledger"],
// https://github.com/zsviczian/obsidian-excalidraw-plugin
["obsidian-excalidraw-plugin", "excalidraw"],
]);

// Helper to make removeOtherExtensions easier.
export const otherExtsSet: Set<string> = new Set(Array.from(otherExts.values()))

/**
* Takes in a list of extensions, and removes extensions if they are present in the values of otherExts.
*
* @param exts extensions to process.
* @returns All extensions in exts, except if they're present in the values of otherExts.
*/
export const removeOtherExtensions = (exts: string[]): string[] => {
return exts.filter(ext => !otherExtsSet.has(ext))
}

/**
* Add typings for a better developer experience.
*/
declare module 'obsidian' {
interface App {
// Thank you javalent#3452 for suggestions on better typing
viewRegistry: {
unregisterView: CallableFunction // ƒ (e){delete this.viewByType[e]}
unregisterExtensions: CallableFunction // ƒ (e){for(var t=0,n=e;t<n.length;t++){var i=n[t];delete this.typeByExtension[i]}this.trigger("extensions-updated")}
unregisterView: (e: string) => void
unregisterExtensions: (e: string[]) => void
},
plugins: {
manifests: [{
id: string
}]
}
}

interface View {
file: {
extension: string
Expand Down
65 changes: 36 additions & 29 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Plugin, WorkspaceLeaf, ViewCreator } from "obsidian";
import { removeObsidianExtensions } from "./helper";
import { removeObsidianExtensions, removeOtherExtensions } from "./helper";
import { PlaintextSettings, PlaintextSettingTab, DEFAULT_SETTINGS } from "./settings";
import PlaintextView from "./view";
import { PlaintextView } from "./view";

/**
* Plaintext plugin.
Expand All @@ -12,7 +12,7 @@ import PlaintextView from "./view";
* Use common sense, and don't edit `.exe` or similar binaries.
*
* @author dbarenholz
* @version 0.1.0
* @version 0.2.0
*/
export default class PlaintextPlugin extends Plugin {
// The settings of the plugin.
Expand All @@ -38,7 +38,6 @@ export default class PlaintextPlugin extends Plugin {
* Code that runs (once) when the plugin is unloaded.
*/
onunload(): void {
// cleanup
this.removeExtensions(this.settings.extensions);
console.log("[Plaintext]: unloaded plugin.");
}
Expand Down Expand Up @@ -67,40 +66,48 @@ export default class PlaintextPlugin extends Plugin {
return new PlaintextView(leaf);
};

/**
* Processes the list of extensions that the user inputs, and removes conflicting ones that should not be added.
*
* @param exts Extensions that are about to be added.
* @returns A finalised list of exts to add.
*/
processConflictingExtensions = (exts: string[]): string[] => {
exts = removeObsidianExtensions(exts)
if (!this.settings.destroyOtherPlugins) {
exts = removeOtherExtensions(exts)
}
return exts
}

/**
* Registers extensions, and makes views for them.
*
* @param exts The extensions to register and add views for.
*/
addExtensions = (exts: string[]): void => {
// Remove obsidian exts just in case
exts = removeObsidianExtensions(exts)
// Process extensions that may conflict with Obsidian or enabled plugins
exts = this.processConflictingExtensions(exts)

// Loop through extensions
exts.forEach((ext) => {
// Try to register view
try {
this.registerView(ext, this.viewCreator);
} catch {
if (this.settings.debug) {
console.log(`[Plaintext]: Extension '${ext}' already has a view registered, ignoring...`);
}
console.log(`[Plaintext]: Extension '${ext}' already has a view registered, ignoring...`);
}

// Try to register extension
try {
// Note: viewtype is set to 'ext' here for possible future expansion to include syntax highlighting based on extension type.
this.registerExtensions([ext], ext);
} catch {
if (this.settings.debug) {
console.log(`[Plaintext]: Extension '${ext}' is already registered, ignoring...`);
}
console.log(`[Plaintext]: Extension '${ext}' is already registered, ignoring...`);
}

// Logging
if (this.settings.debug) {
console.log(`[Plaintext]: added=${ext}`);
}
// DEBUG
console.log(`[Plaintext]: added=${ext}`);
})
};

Expand All @@ -110,37 +117,37 @@ export default class PlaintextPlugin extends Plugin {
* @param exts The extensions to deregister and remove views for.
*/
removeExtensions = (exts: string[]): void => {
// Remove obsidian exts just in case
exts = removeObsidianExtensions(exts)
// Process extensions that may conflict with Obsidian or enabled plugins
exts = this.processConflictingExtensions(exts)

// Try to deregister the views
exts.forEach((ext) => {
// Before unregistering the view: close active leaf if of type ext
if (ext == this.app.workspace.activeLeaf.view.getViewType()) {
// Thank you Licat#1607: activeLeaf could be null here causing a crash => Replaced with getActiveViewOfType
const view = this.app.workspace.getActiveViewOfType(PlaintextView)
if (view && ext == view.getViewType()) {
this.app.workspace.activeLeaf.detach();
}

try {
this.app.viewRegistry.unregisterView(ext)
} catch {
if (this.settings.debug) {
console.log(`[Plaintext]: View for extension '${ext}' cannot be deregistered...`);
}
console.log(`[Plaintext]: View for extension '${ext}' cannot be deregistered...`);

}
});

// Try to deregister the extensions
try {
this.app.viewRegistry.unregisterExtensions(exts)
} catch {
if (this.settings.debug) {
console.log(`[Plaintext]: Cannot deregister extensions...`);
}
}
console.log(`[Plaintext]: Cannot deregister extensions...`);

// Logging
if (this.settings.debug) {
console.log(`[Plaintext]: removed=${exts}`);
}

// DEBUG
console.log(`[Plaintext]: removed=${exts}`);

};

}
Loading

0 comments on commit 3795b4c

Please sign in to comment.