mirror of
https://github.com/pedersen/obsidian-testing-vault.git
synced 2026-07-22 07:30:23 +00:00
* All settings are now respected across all functions
* Fixed links when generating normal nodes (previous would not generate links). * Updated README to reflect current functionality.
This commit is contained in:
parent
35b9e74c9c
commit
c1e9988548
2 changed files with 52 additions and 117 deletions
113
README.md
113
README.md
|
|
@ -1,96 +1,35 @@
|
||||||
# Obsidian Sample Plugin
|
# Obsidian Testing Vault Plugin
|
||||||
|
|
||||||
This is a sample plugin for Obsidian (https://obsidian.md).
|
This plugin is used for making random testing vaults, particularly during
|
||||||
|
plugin development. None of its functions are bound to hotkeys or menu
|
||||||
|
entries, and this is by conscious choice. The functions provided herein
|
||||||
|
are dangerous, and can go so far as to destroy your existing vault.
|
||||||
|
|
||||||
This project uses Typescript to provide type checking and documentation.
|
The random notes command all produce [Lorem Ipsum](https://www.lipsum.com/) text.
|
||||||
The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does.
|
This provides you the ability to know you do not care about the contents.
|
||||||
|
You can still use this to test out your plugin in numerous ways, such as
|
||||||
|
if you are building an alternate rendering system, or statistics, or any
|
||||||
|
such thing where having data in the notes (even if that data is
|
||||||
|
non-sensical) is useful.
|
||||||
|
|
||||||
**Note:** The Obsidian API is still in early alpha and is subject to change at any time!
|
Three commands are provided, accessible via the Mod-P command palette.
|
||||||
|
|
||||||
This sample plugin demonstrates some of the basic functionality the plugin API can do.
|
# Make a single randomized note in your vault
|
||||||
- Changes the default font color to red using `styles.css`.
|
|
||||||
- Adds a ribbon icon, which shows a Notice when clicked.
|
|
||||||
- Adds a command "Open Sample Modal" which opens a Modal.
|
|
||||||
- Adds a plugin setting tab to the settings page.
|
|
||||||
- Registers a global click event and output 'click' to the console.
|
|
||||||
- Registers a global interval which logs 'setInterval' to the console.
|
|
||||||
|
|
||||||
## First time developing plugins?
|
This command simply makes a single random note. Since it does not scan your
|
||||||
|
existing vault, it will not provide links to other notes, nor will they link
|
||||||
|
to it. However, you can use this command to examine the output and see if
|
||||||
|
you are comfortable using the sort of output that will be generated by this
|
||||||
|
plugin.
|
||||||
|
|
||||||
Quick starting guide for new plugin devs:
|
# Make a group of randomized notes in your vault
|
||||||
|
|
||||||
- Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with.
|
This command will show you a dialog box to allow you to tweak the settings
|
||||||
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
|
before generating a group of interconnected notes. This can take a second,
|
||||||
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
|
so it is limited to producing 10,000 notes at a time.
|
||||||
- Install NodeJS, then run `npm i` in the command line under your repo folder.
|
|
||||||
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
|
|
||||||
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
|
|
||||||
- Reload Obsidian to load the new version of your plugin.
|
|
||||||
- Enable plugin in settings window.
|
|
||||||
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
|
|
||||||
|
|
||||||
## Releasing new releases
|
# Destroy everything in this vault
|
||||||
|
|
||||||
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
|
Does exactly what it says: Everything in the vault will be deleted. Does
|
||||||
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
|
*not* ask for confirmation. Don't run this in any vault you care about, as you
|
||||||
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
|
will lose *everything*.
|
||||||
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release.
|
|
||||||
- Publish the release.
|
|
||||||
|
|
||||||
> You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`.
|
|
||||||
> The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json`
|
|
||||||
|
|
||||||
## Adding your plugin to the community plugin list
|
|
||||||
|
|
||||||
- Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md
|
|
||||||
- Publish an initial version.
|
|
||||||
- Make sure you have a `README.md` file in the root of your repo.
|
|
||||||
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
- Clone this repo.
|
|
||||||
- `npm i` or `yarn` to install dependencies
|
|
||||||
- `npm run dev` to start compilation in watch mode.
|
|
||||||
|
|
||||||
## Manually installing the plugin
|
|
||||||
|
|
||||||
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
|
|
||||||
|
|
||||||
## Improve code quality with eslint (optional)
|
|
||||||
- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code.
|
|
||||||
- To use eslint with this project, make sure to install eslint from terminal:
|
|
||||||
- `npm install -g eslint`
|
|
||||||
- To use eslint to analyze this project use this command:
|
|
||||||
- `eslint main.ts`
|
|
||||||
- eslint will then create a report with suggestions for code improvement by file and line number.
|
|
||||||
- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder:
|
|
||||||
- `eslint .\src\`
|
|
||||||
|
|
||||||
## Funding URL
|
|
||||||
|
|
||||||
You can include funding URLs where people who use your plugin can financially support it.
|
|
||||||
|
|
||||||
The simple way is to set the `fundingUrl` field to your link in your `manifest.json` file:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"fundingUrl": "https://buymeacoffee.com"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have multiple URLs, you can also do:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"fundingUrl": {
|
|
||||||
"Buy Me a Coffee": "https://buymeacoffee.com",
|
|
||||||
"GitHub Sponsor": "https://github.com/sponsors",
|
|
||||||
"Patreon": "https://www.patreon.com/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Documentation
|
|
||||||
|
|
||||||
See https://github.com/obsidianmd/obsidian-api
|
|
||||||
|
|
|
||||||
56
main.ts
56
main.ts
|
|
@ -7,9 +7,6 @@ let wrap = require('word-wrap');
|
||||||
/*
|
/*
|
||||||
Defaults for the plugin:
|
Defaults for the plugin:
|
||||||
* Number of notes to make: 1000
|
* Number of notes to make: 1000
|
||||||
* Min number of links to other notes: 1
|
|
||||||
* Max number of links to other notes: 10
|
|
||||||
* Skew towards minimum, make the higher number of links harder to happen
|
|
||||||
|
|
||||||
* From comment on Discord:
|
* From comment on Discord:
|
||||||
You might also want to consider adding other rando text generations, other than lorem ipsum, such as
|
You might also want to consider adding other rando text generations, other than lorem ipsum, such as
|
||||||
|
|
@ -29,8 +26,6 @@ interface INoteGenerator {
|
||||||
maxParagraphs?: number; // 10
|
maxParagraphs?: number; // 10
|
||||||
minTags?: number; // 0
|
minTags?: number; // 0
|
||||||
maxTags?: number; // 5
|
maxTags?: number; // 5
|
||||||
minAliases?: number; // 0
|
|
||||||
maxAliases?: number; // 3
|
|
||||||
aliasPercent?: number; // 10
|
aliasPercent?: number; // 10
|
||||||
publishPercent?: number; // 50
|
publishPercent?: number; // 50
|
||||||
frontMatterPercent?: number; // 90
|
frontMatterPercent?: number; // 90
|
||||||
|
|
@ -110,7 +105,7 @@ function newTitle(titleWords: number): string {
|
||||||
}
|
}
|
||||||
function newLoremNote({title = '', minTitleWords = 4, maxTitleWords = 10, minSentenceWords = 5, maxSentenceWords = 20,
|
function newLoremNote({title = '', minTitleWords = 4, maxTitleWords = 10, minSentenceWords = 5, maxSentenceWords = 20,
|
||||||
minSentences = 4, maxSentences = 20, minParagraphs = 1, maxParagraphs = 10, minTags = 0, maxTags = 5,
|
minSentences = 4, maxSentences = 20, minParagraphs = 1, maxParagraphs = 10, minTags = 0, maxTags = 5,
|
||||||
minAliases = 0, maxAliases = 3, aliasPercent = 10, publishPercent = 50,
|
aliasPercent = 10, publishPercent = 50,
|
||||||
frontMatterPercent = 90, alltitles=[], minLinks=1, maxLinks=10}: INoteGenerator): { note: string, title: string } {
|
frontMatterPercent = 90, alltitles=[], minLinks=1, maxLinks=10}: INoteGenerator): { note: string, title: string } {
|
||||||
const titleWords = randomInt(minTitleWords, maxTitleWords);
|
const titleWords = randomInt(minTitleWords, maxTitleWords);
|
||||||
const numParagraphs = randomInt(minParagraphs, maxParagraphs, 4);
|
const numParagraphs = randomInt(minParagraphs, maxParagraphs, 4);
|
||||||
|
|
@ -123,15 +118,6 @@ function newLoremNote({title = '', minTitleWords = 4, maxTitleWords = 10, minSen
|
||||||
sentenceLowerBound: minSentenceWords, sentenceUpperBound: maxSentenceWords,
|
sentenceLowerBound: minSentenceWords, sentenceUpperBound: maxSentenceWords,
|
||||||
suffix: "\n\n"
|
suffix: "\n\n"
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
* If alltitles.length > 0:
|
|
||||||
* determine number of links
|
|
||||||
* get those subset of article titles from alltitles
|
|
||||||
* split text into paragraphs.
|
|
||||||
* for each link:
|
|
||||||
* pick random paragraph and add link to it
|
|
||||||
* join text back into one string
|
|
||||||
*/
|
|
||||||
if (alltitles?.length > 0) {
|
if (alltitles?.length > 0) {
|
||||||
const numberofLinks = randomInt(minLinks, maxLinks);
|
const numberofLinks = randomInt(minLinks, maxLinks);
|
||||||
const linkedTitles = randomSubset(alltitles, numberofLinks);
|
const linkedTitles = randomSubset(alltitles, numberofLinks);
|
||||||
|
|
@ -148,14 +134,10 @@ function newLoremNote({title = '', minTitleWords = 4, maxTitleWords = 10, minSen
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {emptyFilesPercent=3,
|
async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {emptyFilesPercent=3,
|
||||||
orphanedNotesPercent=5, leafNotesPercent=25, minTitleWords=4, maxTitleWords=10}: INoteGenerator) {
|
orphanedNotesPercent=5, leafNotesPercent=25, minTitleWords=4, maxTitleWords=10,
|
||||||
/*
|
minSentenceWords=5, maxSentenceWords=20, minSentences=4, maxSentences=20, minParagraphs=1, maxParagraphs=10,
|
||||||
* Generate all titles
|
minTags=0, maxTags=5, aliasPercent=10, publishPercent=50, frontMatterPercent=90,
|
||||||
* Generate empty files
|
minLinks=1, maxLinks=10}: INoteGenerator) {
|
||||||
* Generate orphan files
|
|
||||||
* Generate leaf notes
|
|
||||||
*/
|
|
||||||
console.log(`maxNotes: ${maxNotes}`)
|
|
||||||
let titles = Array.apply(null, Array(maxNotes)).map(function () {});
|
let titles = Array.apply(null, Array(maxNotes)).map(function () {});
|
||||||
await notice.setMessage("Generating titles");
|
await notice.setMessage("Generating titles");
|
||||||
for (let i=0; i<maxNotes; i++) {
|
for (let i=0; i<maxNotes; i++) {
|
||||||
|
|
@ -166,7 +148,6 @@ async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {em
|
||||||
await notice.setMessage("Generating Empty Notes");
|
await notice.setMessage("Generating Empty Notes");
|
||||||
let generated = 0;
|
let generated = 0;
|
||||||
const emptyFilesCount = Math.floor(maxNotes*(emptyFilesPercent/100.0));
|
const emptyFilesCount = Math.floor(maxNotes*(emptyFilesPercent/100.0));
|
||||||
console.log(`empty notes: ${emptyFilesCount}`)
|
|
||||||
for (let i=0; i<emptyFilesCount; i++) {
|
for (let i=0; i<emptyFilesCount; i++) {
|
||||||
await vault.create(`${titles[generated]}.md`, '');
|
await vault.create(`${titles[generated]}.md`, '');
|
||||||
generated++;
|
generated++;
|
||||||
|
|
@ -176,9 +157,14 @@ async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {em
|
||||||
const orphanedNotesCount = Math.floor(maxNotes*(orphanedNotesPercent/100.0));
|
const orphanedNotesCount = Math.floor(maxNotes*(orphanedNotesPercent/100.0));
|
||||||
for (let i=0; i<orphanedNotesCount; i++) {
|
for (let i=0; i<orphanedNotesCount; i++) {
|
||||||
if ((i>=1) && (i%20==0)) {
|
if ((i>=1) && (i%20==0)) {
|
||||||
await notice.setMessage(`Progress: Created ${i}/${orphanedNotesCount} orphaned notes so far`);
|
await notice.setMessage(`Progress: Created ${i}/${maxNotes} notes so far`);
|
||||||
}
|
}
|
||||||
let note = newLoremNote({title: titles[generated]});
|
let note = newLoremNote({title: titles[generated],
|
||||||
|
minTitleWords: minLinks, maxTitleWords: maxTitleWords, minSentenceWords: minSentenceWords,
|
||||||
|
maxSentenceWords: maxSentenceWords, minSentences: minSentences, maxSentences: maxSentences,
|
||||||
|
minParagraphs: minParagraphs, maxParagraphs: maxParagraphs, minTags: minTags, maxTags: maxTags,
|
||||||
|
aliasPercent: aliasPercent, publishPercent: publishPercent, frontMatterPercent: frontMatterPercent,
|
||||||
|
minLinks: minLinks, maxLinks: maxLinks});
|
||||||
await vault.create(`${note.title}.md`, note.note);
|
await vault.create(`${note.title}.md`, note.note);
|
||||||
generated++;
|
generated++;
|
||||||
}
|
}
|
||||||
|
|
@ -188,9 +174,14 @@ async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {em
|
||||||
const leafCount = Math.floor(maxNotes*(leafNotesPercent/100.0));
|
const leafCount = Math.floor(maxNotes*(leafNotesPercent/100.0));
|
||||||
for (let i=0; i<leafCount; i++) {
|
for (let i=0; i<leafCount; i++) {
|
||||||
if ((i>=1) && (i%20==0)) {
|
if ((i>=1) && (i%20==0)) {
|
||||||
await notice.setMessage(`Progress: Created ${i}/${orphanedNotesCount} leaf notes so far`);
|
await notice.setMessage(`Progress: Created ${i}/${maxNotes} notes so far`);
|
||||||
}
|
}
|
||||||
let note = newLoremNote({title: titles[generated], alltitles: titles.slice(linksBegin)});
|
let note = newLoremNote({title: titles[generated], alltitles: titles.slice(linksBegin),
|
||||||
|
minTitleWords: minLinks, maxTitleWords: maxTitleWords, minSentenceWords: minSentenceWords,
|
||||||
|
maxSentenceWords: maxSentenceWords, minSentences: minSentences, maxSentences: maxSentences,
|
||||||
|
minParagraphs: minParagraphs, maxParagraphs: maxParagraphs, minTags: minTags, maxTags: maxTags,
|
||||||
|
aliasPercent: aliasPercent, publishPercent: publishPercent, frontMatterPercent: frontMatterPercent,
|
||||||
|
minLinks: minLinks, maxLinks: maxLinks});
|
||||||
await vault.create(`${note.title}.md`, note.note);
|
await vault.create(`${note.title}.md`, note.note);
|
||||||
generated++;
|
generated++;
|
||||||
}
|
}
|
||||||
|
|
@ -199,10 +190,16 @@ async function fillVault(maxNotes: number=100, notice: Notice, vault: Vault, {em
|
||||||
if ((i>=1) && (i%20==0)) {
|
if ((i>=1) && (i%20==0)) {
|
||||||
await notice.setMessage(`Progress: Created ${i}/${maxNotes} notes so far`);
|
await notice.setMessage(`Progress: Created ${i}/${maxNotes} notes so far`);
|
||||||
}
|
}
|
||||||
let note = newLoremNote({minTitleWords:minTitleWords, maxTitleWords:maxTitleWords, title: titles[i]});
|
let note = newLoremNote({title: titles[i], alltitles: titles.slice(linksBegin),
|
||||||
|
minTitleWords: minLinks, maxTitleWords: maxTitleWords, minSentenceWords: minSentenceWords,
|
||||||
|
maxSentenceWords: maxSentenceWords, minSentences: minSentences, maxSentences: maxSentences,
|
||||||
|
minParagraphs: minParagraphs, maxParagraphs: maxParagraphs, minTags: minTags, maxTags: maxTags,
|
||||||
|
aliasPercent: aliasPercent, publishPercent: publishPercent, frontMatterPercent: frontMatterPercent,
|
||||||
|
minLinks: minLinks, maxLinks: maxLinks});
|
||||||
await vault.create(`${note.title}.md`, note.note);
|
await vault.create(`${note.title}.md`, note.note);
|
||||||
}
|
}
|
||||||
await notice.setMessage(`Vault generated ${maxNotes} notes`);
|
await notice.setMessage(`Vault generated ${maxNotes} notes`);
|
||||||
|
setTimeout(() => notice.hide(), 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TestingVaultPluginSettings {
|
interface TestingVaultPluginSettings {
|
||||||
|
|
@ -267,7 +264,6 @@ export default class TestingVaultPlugin extends Plugin {
|
||||||
const maxnotes=100;
|
const maxnotes=100;
|
||||||
let task_status = new Notice('Generating new testing vault', 0);
|
let task_status = new Notice('Generating new testing vault', 0);
|
||||||
fillVault(maxnotes, task_status, this.app.vault, {});
|
fillVault(maxnotes, task_status, this.app.vault, {});
|
||||||
setTimeout(() => task_status.hide(), 4000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue