feat: add some kirchhoffs law
This commit is contained in:
parent
7427cd4657
commit
9966ab367f
3
.obsidian/app.json
vendored
3
.obsidian/app.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"legacyEditor": false
|
|
||||||
}
|
|
3
.obsidian/appearance.json
vendored
3
.obsidian/appearance.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"baseFontSize": 16
|
|
||||||
}
|
|
1
.obsidian/community-plugins.json
vendored
1
.obsidian/community-plugins.json
vendored
@ -1 +0,0 @@
|
|||||||
[]
|
|
15
.obsidian/core-plugins.json
vendored
15
.obsidian/core-plugins.json
vendored
@ -1,15 +0,0 @@
|
|||||||
[
|
|
||||||
"file-explorer",
|
|
||||||
"global-search",
|
|
||||||
"switcher",
|
|
||||||
"graph",
|
|
||||||
"backlink",
|
|
||||||
"page-preview",
|
|
||||||
"note-composer",
|
|
||||||
"command-palette",
|
|
||||||
"editor-status",
|
|
||||||
"markdown-importer",
|
|
||||||
"word-count",
|
|
||||||
"open-with-default-app",
|
|
||||||
"file-recovery"
|
|
||||||
]
|
|
1
.obsidian/hotkeys.json
vendored
1
.obsidian/hotkeys.json
vendored
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1 +0,0 @@
|
|||||||
/main.js linguist-generated
|
|
2
.obsidian/plugins/obsidian-desmos/.gitignore
vendored
2
.obsidian/plugins/obsidian-desmos/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
/data.json
|
|
||||||
/node_modules/
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"tabWidth": 4
|
|
||||||
}
|
|
95
.obsidian/plugins/obsidian-desmos/README.md
vendored
95
.obsidian/plugins/obsidian-desmos/README.md
vendored
@ -1,95 +0,0 @@
|
|||||||
# Obsidian Desmos
|
|
||||||
|
|
||||||
Render [Desmos](https://www.desmos.com/calculator) graphs right inside your notes.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
## Using Git
|
|
||||||
|
|
||||||
If your vault is hosted using git then congratulations, you can use the easy method. Run
|
|
||||||
`git subtree add --prefix .obsidian/plugins/obsidian-desmos https://github.com/Nigecat/obsidian-desmos master --squash`
|
|
||||||
to add the plugin to the vault in the current working directory of your terminal.
|
|
||||||
You can then run
|
|
||||||
`git subtree pull --prefix .obsidian/plugins/obsidian-desmos https://github.com/Nigecat/obsidian-desmos master --squash`
|
|
||||||
to update the plugin to the latest version (from the same working directory).
|
|
||||||
|
|
||||||
## Using anything else
|
|
||||||
|
|
||||||
Alternatively, if you do not use git or are not comfortable using the terminal, you can manually install the plugin. Download [manifest.json](manifest.json), [versions.json](versions.json), and [main.js](main.js) and place them in `<vault>/.obsidian/plugins/obsidian-desmos` (you may have to create any missing folders).
|
|
||||||
This process must be repeated to update the application.
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
The most basic usage of this plugin involves creating a codeblock with the tag `desmos-graph` and placing the equations you wish to graph in the body:
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
y=x
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
Equations use the [LaTeX math](https://en.wikibooks.org/wiki/LaTeX/Mathematics) format and you can graph multiple equations by placing each one on a seperate line:
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
y=\sin(x)
|
|
||||||
y=\frac{1}{x}
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
You can restrict the bounds of the graph and apply other settings by placing a `---` seperator before your equations. The content before it must be a set of `key=value` pairs seperated by either **newlines or semicolons** (or both):
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
boundary_left=0; boundary_right=100;
|
|
||||||
boundary_top=10; boundary_bottom=-10;
|
|
||||||
---
|
|
||||||
y=\sin(x)
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
You can set the dimensions of the rendered image by using the `height` and `width` fields.
|
|
||||||
|
|
||||||
#### Restrictions
|
|
||||||
|
|
||||||
Note that graph restrictions follow the same format as desmos itself (except we use a `|` to denote the beginning of the restrictions):
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
y=\sin(x)|{y > 0}
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
### Style
|
|
||||||
|
|
||||||
We support six different types of (case-insensitive) styles:
|
|
||||||
Line: `SOLID` `DASHED` `DOTTED`
|
|
||||||
Point: `POINT` `OPEN` `CROSS`
|
|
||||||
|
|
||||||
These are placed after the graph restrictions, following another `|`:
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
y=\sin(x)|{y > 0}|DASHED
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
If you do not wish to apply any restrictions, the center field can be left blank:
|
|
||||||
|
|
||||||
````
|
|
||||||
```desmos-graph
|
|
||||||
y=\sin(x)||DASHED
|
|
||||||
(1,2)||OPEN
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
## Important
|
|
||||||
|
|
||||||
Note that to be able to render these graphs into a PDF the following conditions must be fulfilled
|
|
||||||
|
|
||||||
1. Memory caching **must** be enabled
|
|
||||||
2. Obsidian **must** have been restarted since you initially created the graph
|
|
||||||
3. You **must** have viewed the rendered graph in the preview since the restart
|
|
||||||
|
|
||||||
After these are complete, a standard PDF export should work fine.
|
|
||||||
In the future these steps will be removed and you will be able to directly export them.
|
|
406
.obsidian/plugins/obsidian-desmos/main.js
vendored
406
.obsidian/plugins/obsidian-desmos/main.js
vendored
File diff suppressed because one or more lines are too long
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "obsidian-desmos",
|
|
||||||
"name": "Desmos",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"minAppVersion": "0.9.12",
|
|
||||||
"description": "Embed Desmos graphs into your notes",
|
|
||||||
"author": "Nigecat",
|
|
||||||
"isDesktopOnly": true
|
|
||||||
}
|
|
343
.obsidian/plugins/obsidian-desmos/package-lock.json
generated
vendored
343
.obsidian/plugins/obsidian-desmos/package-lock.json
generated
vendored
@ -1,343 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "obsidian-desmos",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"lockfileVersion": 1,
|
|
||||||
"requires": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@rollup/plugin-commonjs": {
|
|
||||||
"version": "19.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-19.0.0.tgz",
|
|
||||||
"integrity": "sha512-adTpD6ATGbehdaQoZQ6ipDFhdjqsTgpOAhFiPwl+dzre4pPshsecptDPyEFb61JMJ1+mGljktaC4jI8ARMSNyw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@rollup/pluginutils": "^3.1.0",
|
|
||||||
"commondir": "^1.0.1",
|
|
||||||
"estree-walker": "^2.0.1",
|
|
||||||
"glob": "^7.1.6",
|
|
||||||
"is-reference": "^1.2.1",
|
|
||||||
"magic-string": "^0.25.7",
|
|
||||||
"resolve": "^1.17.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@rollup/plugin-node-resolve": {
|
|
||||||
"version": "13.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.0.tgz",
|
|
||||||
"integrity": "sha512-41X411HJ3oikIDivT5OKe9EZ6ud6DXudtfNrGbC4nniaxx2esiWjkLOzgnZsWq1IM8YIeL2rzRGLZLBjlhnZtQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@rollup/pluginutils": "^3.1.0",
|
|
||||||
"@types/resolve": "1.17.1",
|
|
||||||
"builtin-modules": "^3.1.0",
|
|
||||||
"deepmerge": "^4.2.2",
|
|
||||||
"is-module": "^1.0.0",
|
|
||||||
"resolve": "^1.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@rollup/plugin-typescript": {
|
|
||||||
"version": "8.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz",
|
|
||||||
"integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@rollup/pluginutils": "^3.1.0",
|
|
||||||
"resolve": "^1.17.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@rollup/pluginutils": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/estree": "0.0.39",
|
|
||||||
"estree-walker": "^1.0.1",
|
|
||||||
"picomatch": "^2.2.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"estree-walker": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/codemirror": {
|
|
||||||
"version": "0.0.108",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz",
|
|
||||||
"integrity": "sha512-3FGFcus0P7C2UOGCNUVENqObEb4SFk+S8Dnxq7K6aIsLVs/vDtlangl3PEO0ykaKXyK56swVF6Nho7VsA44uhw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/tern": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/debounce": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-bWG5wapaWgbss9E238T0R6bfo5Fh3OkeoSt245CM7JJwVwpw6MEBCbIxLq5z8KzsE3uJhzcIuQkyiZmzV3M/Dw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/estree": {
|
|
||||||
"version": "0.0.39",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
|
|
||||||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/node": {
|
|
||||||
"version": "15.12.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
|
|
||||||
"integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/resolve": {
|
|
||||||
"version": "1.17.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
|
||||||
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/tern": {
|
|
||||||
"version": "0.23.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.3.tgz",
|
|
||||||
"integrity": "sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/estree": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"balanced-match": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"brace-expansion": {
|
|
||||||
"version": "1.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"balanced-match": "^1.0.0",
|
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"builtin-modules": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"commondir": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"concat-map": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"deepmerge": {
|
|
||||||
"version": "4.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
|
||||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"estree-walker": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"fsevents": {
|
|
||||||
"version": "2.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"function-bind": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"glob": {
|
|
||||||
"version": "7.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
|
|
||||||
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"has": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"function-bind": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"is-core-module": {
|
|
||||||
"version": "2.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
|
|
||||||
"integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"has": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-module": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"is-reference": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/estree": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"magic-string": {
|
|
||||||
"version": "0.25.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
|
||||||
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"sourcemap-codec": "^1.4.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minimatch": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"moment": {
|
|
||||||
"version": "2.29.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
|
||||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"obsidian": {
|
|
||||||
"version": "0.12.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-0.12.5.tgz",
|
|
||||||
"integrity": "sha512-dQkcHWVgPzVlCxvkeu02Co8P1t4Ii95dC2NsFJV5bKK04J4//YxEdTTI/TFKr77CtYcH78LlUmOFeY5rHwyU/Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/codemirror": "0.0.108",
|
|
||||||
"moment": "2.29.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"path-is-absolute": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"path-parse": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"picomatch": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"resolve": {
|
|
||||||
"version": "1.20.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
|
||||||
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-core-module": "^2.2.0",
|
|
||||||
"path-parse": "^1.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rollup": {
|
|
||||||
"version": "2.51.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.51.2.tgz",
|
|
||||||
"integrity": "sha512-ReV2eGEadA7hmXSzjxdDKs10neqH2QURf2RxJ6ayAlq93ugy6qIvXMmbc5cWMGCDh1h5T4thuWO1e2VNbMq8FA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fsevents": "~2.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourcemap-codec": {
|
|
||||||
"version": "1.4.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
|
||||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"tslib": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"version": "4.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz",
|
|
||||||
"integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
22
.obsidian/plugins/obsidian-desmos/package.json
vendored
22
.obsidian/plugins/obsidian-desmos/package.json
vendored
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "obsidian-desmos",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"description": "Embed Desmos graphs into your notes",
|
|
||||||
"main": "main.js",
|
|
||||||
"author": "Nigecat",
|
|
||||||
"scripts": {
|
|
||||||
"build": "rollup --config rollup.config.js --environment BUILD:production",
|
|
||||||
"build:dev": "rollup --config rollup.config.js -w"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@rollup/plugin-commonjs": "^19.0.0",
|
|
||||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
||||||
"@rollup/plugin-typescript": "^8.2.1",
|
|
||||||
"@types/debounce": "^1.2.0",
|
|
||||||
"@types/node": "^15.12.2",
|
|
||||||
"obsidian": "^0.12.5",
|
|
||||||
"rollup": "^2.51.2",
|
|
||||||
"tslib": "^2.3.0",
|
|
||||||
"typescript": "^4.3.2"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import typescript from "@rollup/plugin-typescript";
|
|
||||||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
|
||||||
|
|
||||||
const isProd = process.env.BUILD === "production";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
input: "src/main.ts",
|
|
||||||
output: {
|
|
||||||
dir: ".",
|
|
||||||
sourcemap: "inline",
|
|
||||||
sourcemapExcludeSources: isProd,
|
|
||||||
format: "cjs",
|
|
||||||
exports: "default",
|
|
||||||
},
|
|
||||||
external: ["obsidian"],
|
|
||||||
plugins: [typescript(), nodeResolve({ browser: true }), commonjs()],
|
|
||||||
};
|
|
141
.obsidian/plugins/obsidian-desmos/src/dsl.ts
vendored
141
.obsidian/plugins/obsidian-desmos/src/dsl.ts
vendored
@ -1,141 +0,0 @@
|
|||||||
import { createHash } from "crypto";
|
|
||||||
|
|
||||||
export interface Fields {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
boundary_left: number;
|
|
||||||
boundary_right: number;
|
|
||||||
boundary_bottom: number;
|
|
||||||
boundary_top: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FIELD_DEFAULTS: Fields = {
|
|
||||||
width: 600,
|
|
||||||
height: 400,
|
|
||||||
boundary_left: -10,
|
|
||||||
boundary_right: 10,
|
|
||||||
boundary_bottom: -7,
|
|
||||||
boundary_top: 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class Dsl {
|
|
||||||
/** A (hex) SHA-256 hash of the fields of this object */
|
|
||||||
public readonly hash: string;
|
|
||||||
public readonly equations: string[];
|
|
||||||
public readonly fields: Fields;
|
|
||||||
|
|
||||||
private constructor(equations: string[], fields: Partial<Fields>) {
|
|
||||||
this.equations = equations;
|
|
||||||
this.fields = { ...FIELD_DEFAULTS, ...fields };
|
|
||||||
Dsl.assert_sanity(this.fields);
|
|
||||||
this.hash = createHash("sha256")
|
|
||||||
.update(JSON.stringify(this))
|
|
||||||
.digest("hex");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check if the fields are sane, throws a `SyntaxError` if they aren't */
|
|
||||||
private static assert_sanity(fields: Fields) {
|
|
||||||
// Ensure boundaries are complete and in order
|
|
||||||
if (fields.boundary_left >= fields.boundary_right) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
`Right boundary (${fields.boundary_right}) must be greater than left boundary (${fields.boundary_left})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fields.boundary_bottom >= fields.boundary_top) {
|
|
||||||
throw new SyntaxError(`
|
|
||||||
Top boundary (${fields.boundary_top}) must be greater than bottom boundary (${fields.boundary_bottom})
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static parse(source: string): Dsl {
|
|
||||||
const split = source.split("---");
|
|
||||||
|
|
||||||
let equations: string[];
|
|
||||||
let fields: Partial<Fields>;
|
|
||||||
switch (split.length) {
|
|
||||||
case 0: {
|
|
||||||
equations = [];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: {
|
|
||||||
equations = split[0].split("\n").filter(Boolean);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: {
|
|
||||||
// If there are two segments then we know the first one must contain the settings
|
|
||||||
fields = split[0]
|
|
||||||
// Allow either a newline or semicolon as a delimiter
|
|
||||||
.split(/[;\n]+/)
|
|
||||||
.map((setting) => setting.trim())
|
|
||||||
// Remove any empty elements
|
|
||||||
.filter(Boolean)
|
|
||||||
// Split each field on the first equals sign to create the key=value pair
|
|
||||||
.map((setting) => {
|
|
||||||
const [key, ...value] = setting.split("=");
|
|
||||||
return [key, value.join("=")];
|
|
||||||
})
|
|
||||||
.reduce((settings, [key, value]) => {
|
|
||||||
if (FIELD_DEFAULTS.hasOwnProperty(key)) {
|
|
||||||
if (!value) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
`Field '${key}' must have a value`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can use the defaults to determine the type of each field
|
|
||||||
const field_v = (FIELD_DEFAULTS as any)[key];
|
|
||||||
const field_t = typeof field_v;
|
|
||||||
|
|
||||||
switch (field_t) {
|
|
||||||
case "number": {
|
|
||||||
const s = parseInt(value);
|
|
||||||
if (Number.isNaN(s)) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
`Field '${key}' must have an integer value`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
(settings as any)[key] = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "string": {
|
|
||||||
(settings as any)[key] = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "object": {
|
|
||||||
const val = JSON.parse(value);
|
|
||||||
if (
|
|
||||||
val.constructor === field_v.constructor
|
|
||||||
) {
|
|
||||||
(settings as any)[key] = val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new SyntaxError(`Unrecognised field: ${key}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return settings;
|
|
||||||
}, {} as Partial<Fields>);
|
|
||||||
|
|
||||||
equations = split[1].split("\n").filter(Boolean);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
fields = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!equations) {
|
|
||||||
throw new SyntaxError("Too many segments");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Dsl(equations, fields);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export function renderError(err: string, el: HTMLElement) {
|
|
||||||
el.innerHTML = `
|
|
||||||
<div style="padding: 20px; background-color: #f44336; color: white;">
|
|
||||||
<strong>Desmos Graph Error:</strong> ${err}
|
|
||||||
</div>`;
|
|
||||||
}
|
|
64
.obsidian/plugins/obsidian-desmos/src/main.ts
vendored
64
.obsidian/plugins/obsidian-desmos/src/main.ts
vendored
@ -1,64 +0,0 @@
|
|||||||
import { Dsl } from "./dsl";
|
|
||||||
import { Renderer } from "./renderer";
|
|
||||||
import { renderError } from "./error";
|
|
||||||
import { debounce, Plugin } from "obsidian";
|
|
||||||
import { Settings, SettingsTab, DEFAULT_SETTINGS } from "./settings";
|
|
||||||
|
|
||||||
export default class Desmos extends Plugin {
|
|
||||||
settings: Settings;
|
|
||||||
/** Helper for in-memory graph caching */
|
|
||||||
graph_cache: Record<string, string>;
|
|
||||||
|
|
||||||
async onload() {
|
|
||||||
this.graph_cache = {};
|
|
||||||
await this.loadSettings();
|
|
||||||
this.addSettingTab(new SettingsTab(this.app, this));
|
|
||||||
|
|
||||||
// Keep track of the total number of graphs in each file
|
|
||||||
// This allows us to skip the debounce on recently opened files to make it feel snappier to use
|
|
||||||
let total = 0;
|
|
||||||
this.app.workspace.on("file-open", async (file) => {
|
|
||||||
const contents = await this.app.vault.cachedRead(file);
|
|
||||||
|
|
||||||
// Attempt to figure out the number of graphs there are in this file
|
|
||||||
// In this case it is fine if we overestimate because we only need a general idea since this just makes it skip the debounce
|
|
||||||
total = (contents.match(/```desmos-graph/g) || []).length;
|
|
||||||
});
|
|
||||||
|
|
||||||
const render = (source: string, el: HTMLElement) => {
|
|
||||||
try {
|
|
||||||
Renderer.render(Dsl.parse(source), this.settings, el, this);
|
|
||||||
} catch (err) {
|
|
||||||
renderError(err.message, el);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const debounce_render = debounce(
|
|
||||||
(source: string, el: HTMLElement) => render(source, el),
|
|
||||||
this.settings.debounce
|
|
||||||
);
|
|
||||||
this.registerMarkdownCodeBlockProcessor(
|
|
||||||
"desmos-graph",
|
|
||||||
(source, el) => {
|
|
||||||
if (total > 0) {
|
|
||||||
total--;
|
|
||||||
// Skip the debounce on initial render
|
|
||||||
render(source, el);
|
|
||||||
} else {
|
|
||||||
debounce_render(source, el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadSettings() {
|
|
||||||
this.settings = Object.assign(
|
|
||||||
{},
|
|
||||||
DEFAULT_SETTINGS,
|
|
||||||
await this.loadData()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async saveSettings() {
|
|
||||||
await this.saveData(this.settings);
|
|
||||||
}
|
|
||||||
}
|
|
205
.obsidian/plugins/obsidian-desmos/src/renderer.ts
vendored
205
.obsidian/plugins/obsidian-desmos/src/renderer.ts
vendored
@ -1,205 +0,0 @@
|
|||||||
import path from "path";
|
|
||||||
import Desmos from "./main";
|
|
||||||
import { Dsl } from "./dsl";
|
|
||||||
import { tmpdir } from "os";
|
|
||||||
import { Notice } from "obsidian";
|
|
||||||
import { Settings } from "./settings";
|
|
||||||
import { renderError } from "./error";
|
|
||||||
import { existsSync, promises as fs } from "fs";
|
|
||||||
|
|
||||||
export class Renderer {
|
|
||||||
static render(
|
|
||||||
args: Dsl,
|
|
||||||
settings: Settings,
|
|
||||||
el: HTMLElement,
|
|
||||||
plugin: Desmos
|
|
||||||
) {
|
|
||||||
const { fields, equations, hash } = args;
|
|
||||||
|
|
||||||
// Calculate cache info for filesystem caching
|
|
||||||
const vault_root = (plugin.app.vault.adapter as any).basePath;
|
|
||||||
const cache_dir = settings.cache_directory
|
|
||||||
? path.isAbsolute(settings.cache_directory)
|
|
||||||
? settings.cache_directory
|
|
||||||
: path.join(vault_root, settings.cache_directory)
|
|
||||||
: tmpdir();
|
|
||||||
const cache_target = path.join(cache_dir, `desmos-graph-${hash}.png`);
|
|
||||||
|
|
||||||
// If this graph is in the cache then fetch it
|
|
||||||
if (settings.cache) {
|
|
||||||
if (
|
|
||||||
settings.cache_location == "memory" &&
|
|
||||||
hash in plugin.graph_cache
|
|
||||||
) {
|
|
||||||
const data = plugin.graph_cache[hash];
|
|
||||||
const img = document.createElement("img");
|
|
||||||
img.src = data;
|
|
||||||
el.appendChild(img);
|
|
||||||
return;
|
|
||||||
} else if (
|
|
||||||
settings.cache_location == "filesystem" &&
|
|
||||||
existsSync(cache_target)
|
|
||||||
) {
|
|
||||||
fs.readFile(cache_target).then((data) => {
|
|
||||||
const b64 =
|
|
||||||
"data:image/png;base64," +
|
|
||||||
Buffer.from(data).toString("base64");
|
|
||||||
const img = document.createElement("img");
|
|
||||||
img.src = b64;
|
|
||||||
el.appendChild(img);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const expressions = equations.map(
|
|
||||||
(equation) =>
|
|
||||||
`calculator.setExpression({
|
|
||||||
latex: "${equation.split("|")[0].replace("\\", "\\\\")}${(
|
|
||||||
equation.split("|")[1] ?? ""
|
|
||||||
)
|
|
||||||
.replace("{", "\\\\{")
|
|
||||||
.replace("}", "\\\\}")
|
|
||||||
.replace("<=", "\\\\leq ")
|
|
||||||
.replace(">=", "\\\\geq ")
|
|
||||||
.replace("<", "\\\\le ")
|
|
||||||
.replace(">", "\\\\ge ")}",
|
|
||||||
|
|
||||||
${(() => {
|
|
||||||
const mode = equation.split("|")[2];
|
|
||||||
|
|
||||||
if (mode) {
|
|
||||||
if (
|
|
||||||
["solid", "dashed", "dotted"].contains(
|
|
||||||
mode.toLowerCase()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return `lineStyle: Desmos.Styles.${mode.toUpperCase()}`;
|
|
||||||
} else if (
|
|
||||||
["point", "open", "cross"].contains(
|
|
||||||
mode.toLowerCase()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return `pointStyle: Desmos.Styles.${mode.toUpperCase()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
})()}
|
|
||||||
});`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Because of the electron sandboxing we have to do this inside an iframe,
|
|
||||||
// otherwise we can't include the desmos API (although it would be nice if they had a REST API of some sort)
|
|
||||||
const html_src_head = `<script src="https://www.desmos.com/api/v1.6/calculator.js?apiKey=dcb31709b452b1cf9dc26972add0fda6"></script>`;
|
|
||||||
const html_src_body = `
|
|
||||||
<div id="calculator" style="width: ${fields.width}px; height: ${
|
|
||||||
fields.height
|
|
||||||
}px;"></div>
|
|
||||||
<script>
|
|
||||||
const options = {
|
|
||||||
settingsMenu: false,
|
|
||||||
expressions: false,
|
|
||||||
lockViewPort: true,
|
|
||||||
zoomButtons: false,
|
|
||||||
trace: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const calculator = Desmos.GraphingCalculator(document.getElementById("calculator"), options);
|
|
||||||
calculator.setMathBounds({
|
|
||||||
left: ${fields.boundary_left},
|
|
||||||
right: ${fields.boundary_right},
|
|
||||||
top: ${fields.boundary_top},
|
|
||||||
bottom: ${fields.boundary_bottom},
|
|
||||||
});
|
|
||||||
|
|
||||||
${expressions.join("")}
|
|
||||||
|
|
||||||
calculator.observe("expressionAnalysis", () => {
|
|
||||||
for (const id in calculator.expressionAnalysis) {
|
|
||||||
const analysis = calculator.expressionAnalysis[id];
|
|
||||||
if (analysis.isError) {
|
|
||||||
parent.postMessage({ t: "desmos-graph", d: "error", data: analysis.errorMessage, hash: "${hash}" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
calculator.asyncScreenshot({ showLabels: true, format: "png" }, (data) => {
|
|
||||||
document.body.innerHTML = "";
|
|
||||||
parent.postMessage({ t: "desmos-graph", d: "render", data, hash: "${hash}" }, "app://obsidian.md");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
`;
|
|
||||||
const html_src = `<html><head>${html_src_head}</head><body>${html_src_body}</body>`;
|
|
||||||
|
|
||||||
const iframe = document.createElement("iframe");
|
|
||||||
iframe.width = fields.width.toString();
|
|
||||||
iframe.height = fields.height.toString();
|
|
||||||
iframe.style.border = "none";
|
|
||||||
iframe.scrolling = "no"; // fixme use a non-depreciated function
|
|
||||||
iframe.srcdoc = html_src;
|
|
||||||
// iframe.style.display = "none"; //fixme hiding the iframe breaks the positioning
|
|
||||||
|
|
||||||
el.appendChild(iframe);
|
|
||||||
|
|
||||||
const handler = (
|
|
||||||
message: MessageEvent<{
|
|
||||||
t: string;
|
|
||||||
d: string;
|
|
||||||
data: string;
|
|
||||||
hash: string;
|
|
||||||
}>
|
|
||||||
) => {
|
|
||||||
if (
|
|
||||||
message.origin === "app://obsidian.md" &&
|
|
||||||
message.data.t === "desmos-graph" &&
|
|
||||||
message.data.hash === hash
|
|
||||||
) {
|
|
||||||
el.empty();
|
|
||||||
|
|
||||||
if (message.data.d === "error") {
|
|
||||||
renderError(message.data.data, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.data.d === "render") {
|
|
||||||
const { data } = message.data;
|
|
||||||
window.removeEventListener("message", handler);
|
|
||||||
|
|
||||||
const img = document.createElement("img");
|
|
||||||
img.src = data;
|
|
||||||
el.appendChild(img);
|
|
||||||
|
|
||||||
if (settings.cache) {
|
|
||||||
if (settings.cache_location == "memory") {
|
|
||||||
plugin.graph_cache[hash] = data;
|
|
||||||
} else if (settings.cache_location == "filesystem") {
|
|
||||||
if (existsSync(cache_dir)) {
|
|
||||||
fs.writeFile(
|
|
||||||
cache_target,
|
|
||||||
data.replace(
|
|
||||||
/^data:image\/png;base64,/,
|
|
||||||
""
|
|
||||||
),
|
|
||||||
"base64"
|
|
||||||
).catch(
|
|
||||||
(err) =>
|
|
||||||
new Notice(
|
|
||||||
`desmos-graph: unexpected error when trying to cache graph: ${err}`,
|
|
||||||
10000
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
new Notice(
|
|
||||||
`desmos-graph: cache directory not found: '${cache_dir}'`,
|
|
||||||
10000
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("message", handler);
|
|
||||||
}
|
|
||||||
}
|
|
105
.obsidian/plugins/obsidian-desmos/src/settings.ts
vendored
105
.obsidian/plugins/obsidian-desmos/src/settings.ts
vendored
@ -1,105 +0,0 @@
|
|||||||
import { tmpdir } from "os";
|
|
||||||
import Desmos from "./main";
|
|
||||||
import { PluginSettingTab, App, Setting } from "obsidian";
|
|
||||||
|
|
||||||
export interface Settings {
|
|
||||||
debounce: number;
|
|
||||||
cache: boolean;
|
|
||||||
cache_location: "memory" | "filesystem";
|
|
||||||
cache_directory: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: Settings = {
|
|
||||||
debounce: 500,
|
|
||||||
cache: true,
|
|
||||||
cache_location: "memory",
|
|
||||||
cache_directory: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class SettingsTab extends PluginSettingTab {
|
|
||||||
plugin: Desmos;
|
|
||||||
|
|
||||||
constructor(app: App, plugin: Desmos) {
|
|
||||||
super(app, plugin);
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
display() {
|
|
||||||
let { containerEl } = this;
|
|
||||||
|
|
||||||
containerEl.empty();
|
|
||||||
|
|
||||||
new Setting(containerEl)
|
|
||||||
.setName("Debounce Time (ms)")
|
|
||||||
.setDesc(
|
|
||||||
"How long to wait after a keypress to render the graph (requires restart to take effect)"
|
|
||||||
)
|
|
||||||
.addText((text) =>
|
|
||||||
text
|
|
||||||
.setValue(this.plugin.settings.debounce.toString())
|
|
||||||
.onChange(async (value) => {
|
|
||||||
const val = parseInt(value);
|
|
||||||
this.plugin.settings.debounce =
|
|
||||||
val === NaN ? DEFAULT_SETTINGS.debounce : val;
|
|
||||||
await this.plugin.saveSettings();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
new Setting(containerEl)
|
|
||||||
.setName("Cache")
|
|
||||||
.setDesc("Whether to cache the rendered graphs")
|
|
||||||
.addToggle((toggle) =>
|
|
||||||
toggle
|
|
||||||
.setValue(this.plugin.settings.cache)
|
|
||||||
.onChange(async (value) => {
|
|
||||||
this.plugin.settings.cache = value;
|
|
||||||
await this.plugin.saveSettings();
|
|
||||||
|
|
||||||
// Reset the display so the new state can render
|
|
||||||
this.display();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.plugin.settings.cache) {
|
|
||||||
new Setting(containerEl)
|
|
||||||
.setName("Cache in memory (alternate: filesystem)")
|
|
||||||
.setDesc(
|
|
||||||
"Cache rendered graphs in memory or on the filesystem (note that memory caching is not persistent)."
|
|
||||||
)
|
|
||||||
.addToggle((toggle) =>
|
|
||||||
toggle
|
|
||||||
.setValue(
|
|
||||||
this.plugin.settings.cache_location === "memory"
|
|
||||||
? true
|
|
||||||
: false
|
|
||||||
)
|
|
||||||
.onChange(async (value) => {
|
|
||||||
this.plugin.settings.cache_location = value
|
|
||||||
? "memory"
|
|
||||||
: "filesystem";
|
|
||||||
await this.plugin.saveSettings();
|
|
||||||
|
|
||||||
// Reset the display so the new state can render
|
|
||||||
this.display();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.plugin.settings.cache_location == "filesystem") {
|
|
||||||
new Setting(containerEl)
|
|
||||||
.setName("Cache Directory")
|
|
||||||
.setDesc(
|
|
||||||
"The directory to save cached graphs in (technical note: the graphs will be saved as `desmos-graph-<hash>.png` where the name is a SHA-256 hash of the graph source). The default directory is the system tempdir for your current operating system, and this value may be either a path relative to the root of your vault or an absolute path. Also note that a lot of junk will be saved to this folder, you have been warned."
|
|
||||||
)
|
|
||||||
.addText((text) =>
|
|
||||||
text
|
|
||||||
.setPlaceholder(tmpdir())
|
|
||||||
.setValue(this.plugin.settings.cache_directory)
|
|
||||||
.onChange(async (value) => {
|
|
||||||
this.plugin.settings.cache_directory = value;
|
|
||||||
await this.plugin.saveSettings();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
*
|
|
||||||
!.gitignore
|
|
||||||
!/plugins/**/*
|
|
@ -1 +0,0 @@
|
|||||||
../../../../main.js
|
|
@ -1 +0,0 @@
|
|||||||
../../../../manifest.json
|
|
@ -1 +0,0 @@
|
|||||||
../../../../versions.json
|
|
@ -1,9 +0,0 @@
|
|||||||
```desmos-graph
|
|
||||||
boundary_left=-2; boundary_right=2;
|
|
||||||
boundary_bottom=-1; boundary_top=3;
|
|
||||||
---
|
|
||||||
y=x^2|{x<0}|DASHED
|
|
||||||
y=x||DOTTED
|
|
||||||
(1,2)||OPEN
|
|
||||||
(-1,2)||CROSS
|
|
||||||
```
|
|
16
.obsidian/plugins/obsidian-desmos/tsconfig.json
vendored
16
.obsidian/plugins/obsidian-desmos/tsconfig.json
vendored
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"inlineSourceMap": true,
|
|
||||||
"inlineSources": true,
|
|
||||||
"module": "ESNext",
|
|
||||||
"target": "es6",
|
|
||||||
"allowJs": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"importHelpers": true,
|
|
||||||
"lib": ["dom", "es5", "scripthost", "es2015"]
|
|
||||||
},
|
|
||||||
"include": ["**/*.ts"]
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"0.0.1": "0.9.12"
|
|
||||||
}
|
|
@ -1,525 +0,0 @@
|
|||||||
/*
|
|
||||||
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
||||||
if you want to view the source, please visit the github repository of this plugin
|
|
||||||
*/
|
|
||||||
|
|
||||||
var __create = Object.create;
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __getProtoOf = Object.getPrototypeOf;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
||||||
var __export = (target, all) => {
|
|
||||||
__markAsModule(target);
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __reExport = (target, module2, desc) => {
|
|
||||||
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
||||||
for (let key of __getOwnPropNames(module2))
|
|
||||||
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
||||||
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
};
|
|
||||||
var __toModule = (module2) => {
|
|
||||||
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
||||||
};
|
|
||||||
var __async = (__this, __arguments, generator) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
var fulfilled = (value) => {
|
|
||||||
try {
|
|
||||||
step(generator.next(value));
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var rejected = (value) => {
|
|
||||||
try {
|
|
||||||
step(generator.throw(value));
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
||||||
step((generator = generator.apply(__this, __arguments)).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/main.ts
|
|
||||||
__export(exports, {
|
|
||||||
default: () => LatexEnvironments
|
|
||||||
});
|
|
||||||
var import_obsidian3 = __toModule(require("obsidian"));
|
|
||||||
|
|
||||||
// src/settings.ts
|
|
||||||
var LatexEnvironmentsSettings = class {
|
|
||||||
constructor() {
|
|
||||||
this.defaultEnvironment = "multline";
|
|
||||||
this.customEnvironments = [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function ensureSettings(loaded) {
|
|
||||||
var _a, _b;
|
|
||||||
const settings = new LatexEnvironmentsSettings();
|
|
||||||
settings.defaultEnvironment = (_a = loaded.defaultEnvironment) != null ? _a : settings.defaultEnvironment;
|
|
||||||
settings.customEnvironments = (_b = loaded.customEnvironments) != null ? _b : settings.customEnvironments;
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/search.ts
|
|
||||||
var SearchCursor = class {
|
|
||||||
constructor(text, regex, _originalCaret) {
|
|
||||||
this.text = text;
|
|
||||||
this._originalCaret = _originalCaret;
|
|
||||||
if (regex instanceof RegExp) {
|
|
||||||
this.regex = regex;
|
|
||||||
} else {
|
|
||||||
this.regex = new RegExp(regex);
|
|
||||||
}
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
reset() {
|
|
||||||
this._from = this._originalCaret;
|
|
||||||
this._to = this._originalCaret;
|
|
||||||
this._caret = this._originalCaret;
|
|
||||||
}
|
|
||||||
findNext() {
|
|
||||||
const text = this.text.slice(this._caret);
|
|
||||||
const match = text.match(this.regex);
|
|
||||||
if ((match == null ? void 0 : match.index) == null) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
this._from = this._caret + match.index;
|
|
||||||
this._to = this._caret + match.index + match[0].length;
|
|
||||||
this._caret = this._to;
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
findPrevious() {
|
|
||||||
const reverseRegex = new RegExp(`(?<full>${this.regex.source})(?!.*[\\r\\n]*.*\\k<full>)`, this.regex.flags);
|
|
||||||
const text = this.text.slice(0, this._caret);
|
|
||||||
const lastMatch = text.match(reverseRegex);
|
|
||||||
if ((lastMatch == null ? void 0 : lastMatch.index) == null || (lastMatch == null ? void 0 : lastMatch.groups) == null) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
this._from = lastMatch.index;
|
|
||||||
this._to = lastMatch.index + lastMatch.groups.full.length;
|
|
||||||
this._caret = this._from;
|
|
||||||
return lastMatch;
|
|
||||||
}
|
|
||||||
to() {
|
|
||||||
return this._to;
|
|
||||||
}
|
|
||||||
from() {
|
|
||||||
return this._from;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/mathblock.ts
|
|
||||||
var MathBlock = class {
|
|
||||||
constructor(text, cursor) {
|
|
||||||
this.text = text;
|
|
||||||
const searchCursor = new SearchCursor(text, "\\$\\$", cursor);
|
|
||||||
this.startPosition = searchCursor.findPrevious() != null ? searchCursor.to() : 0;
|
|
||||||
searchCursor.reset();
|
|
||||||
this.endPosition = searchCursor.findNext() != null ? searchCursor.from() : text.length;
|
|
||||||
}
|
|
||||||
getEnclosingEnvironment(cursor) {
|
|
||||||
const beginEnds = new BeginEnds(this.text, this.startPosition, this.endPosition);
|
|
||||||
const environments = Array.from(beginEnds);
|
|
||||||
if (beginEnds.isOpen) {
|
|
||||||
throw new Error("unclosed environments in block");
|
|
||||||
}
|
|
||||||
const start = environments.filter((env) => env.type === "begin" && env.from < cursor).pop();
|
|
||||||
if (start === void 0) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
const after = environments.filter((env) => env.from > start.to);
|
|
||||||
let open = 1;
|
|
||||||
let end;
|
|
||||||
for (const env of after) {
|
|
||||||
if (env.type === "begin") {
|
|
||||||
open++;
|
|
||||||
} else {
|
|
||||||
open--;
|
|
||||||
if (open === 0) {
|
|
||||||
end = env;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (end === void 0) {
|
|
||||||
throw new Error("current environment is never closed");
|
|
||||||
}
|
|
||||||
if (end.to < cursor) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
name: start.name,
|
|
||||||
begin: start,
|
|
||||||
end,
|
|
||||||
contents: this.text.slice(start.to, end.from)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
static isMathMode(_cursor, _editor) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var BeginEnds = class {
|
|
||||||
constructor(text, start, end) {
|
|
||||||
this.text = text;
|
|
||||||
this.start = start;
|
|
||||||
this.end = end;
|
|
||||||
this.openEnvs = [];
|
|
||||||
this.search = this.getEnvCursor(this.start);
|
|
||||||
}
|
|
||||||
reset() {
|
|
||||||
this.search = this.getEnvCursor(this.start);
|
|
||||||
}
|
|
||||||
getEnvCursor(start) {
|
|
||||||
return new SearchCursor(this.text, /\\(?<beginEnd>begin|end){\s*(?<name>[^}]+)\s*}/m, start);
|
|
||||||
}
|
|
||||||
get isOpen() {
|
|
||||||
return this.openEnvs.length > 0;
|
|
||||||
}
|
|
||||||
[Symbol.iterator]() {
|
|
||||||
this.reset();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
next() {
|
|
||||||
const match = this.search.findNext();
|
|
||||||
const to = this.search.to();
|
|
||||||
if ((match == null ? void 0 : match.groups) == null || to > this.end) {
|
|
||||||
return { done: true, value: null };
|
|
||||||
}
|
|
||||||
switch (match.groups.beginEnd) {
|
|
||||||
case "begin": {
|
|
||||||
const current = {
|
|
||||||
name: match.groups.name,
|
|
||||||
type: "begin",
|
|
||||||
from: this.search.from(),
|
|
||||||
to: this.search.to()
|
|
||||||
};
|
|
||||||
this.openEnvs.push(current);
|
|
||||||
return {
|
|
||||||
done: false,
|
|
||||||
value: current
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "end": {
|
|
||||||
const current = this.openEnvs.pop();
|
|
||||||
if (current === void 0) {
|
|
||||||
throw new Error("closing environment which was never opened");
|
|
||||||
}
|
|
||||||
if (current.name !== match.groups.name) {
|
|
||||||
throw new Error("environment not closed properly");
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
done: false,
|
|
||||||
value: {
|
|
||||||
name: match.groups.name,
|
|
||||||
type: "end",
|
|
||||||
from: this.search.from(),
|
|
||||||
to: this.search.to()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error(`regex returned unexpected result ${match[1]}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/envmodal.ts
|
|
||||||
var import_obsidian = __toModule(require("obsidian"));
|
|
||||||
|
|
||||||
// src/environmentNames.ts
|
|
||||||
var DISPLAY_EQUATIONS = [
|
|
||||||
"equation",
|
|
||||||
"equation*",
|
|
||||||
"gather",
|
|
||||||
"gather*",
|
|
||||||
"multline",
|
|
||||||
"multline*",
|
|
||||||
"split",
|
|
||||||
"align",
|
|
||||||
"align*",
|
|
||||||
"flalign",
|
|
||||||
"flalign*",
|
|
||||||
"alignat",
|
|
||||||
"alignat*"
|
|
||||||
];
|
|
||||||
var MATRICES = [
|
|
||||||
"matrix",
|
|
||||||
"pmatrix",
|
|
||||||
"bmatrix",
|
|
||||||
"Bmatrix",
|
|
||||||
"vmatrix",
|
|
||||||
"Vmatrix",
|
|
||||||
"smallmatrix"
|
|
||||||
];
|
|
||||||
var SUB_ENVIRONMENTS = ["multlined", "gathered", "aligned", "cases"];
|
|
||||||
var DEFAULT_ENVIRONMENTS = [
|
|
||||||
...DISPLAY_EQUATIONS,
|
|
||||||
...MATRICES,
|
|
||||||
...SUB_ENVIRONMENTS
|
|
||||||
];
|
|
||||||
|
|
||||||
// src/envmodal.ts
|
|
||||||
var EnvModal = class extends import_obsidian.FuzzySuggestModal {
|
|
||||||
constructor(app, settings, name, callback) {
|
|
||||||
super(app);
|
|
||||||
this.settings = settings;
|
|
||||||
this.name = name;
|
|
||||||
this.callback = callback;
|
|
||||||
this.matched = false;
|
|
||||||
this.setInstructions([
|
|
||||||
{ command: "\u2191\u2193", purpose: "to navigate" },
|
|
||||||
{ command: "\u21B5", purpose: "to select" },
|
|
||||||
{ command: "esc", purpose: "to dismiss" }
|
|
||||||
]);
|
|
||||||
this.setPlaceholder("environment name");
|
|
||||||
}
|
|
||||||
getItems() {
|
|
||||||
return Array.from(new Set([this.settings.defaultEnvironment].concat(this.settings.customEnvironments, DEFAULT_ENVIRONMENTS)));
|
|
||||||
}
|
|
||||||
getItemText(item) {
|
|
||||||
this.matched = true;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
onNoSuggestion() {
|
|
||||||
this.matched = false;
|
|
||||||
}
|
|
||||||
onChooseItem(item, _evt) {
|
|
||||||
if (this.matched) {
|
|
||||||
this.callback(item);
|
|
||||||
} else {
|
|
||||||
this.callback(this.inputEl.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static callback(app, settings, defaultName, call) {
|
|
||||||
new EnvModal(app, settings, defaultName, call).open();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/latexEnvironmentsSettingsTab.ts
|
|
||||||
var import_obsidian2 = __toModule(require("obsidian"));
|
|
||||||
var LatexEnvironmentsSettingTab = class extends import_obsidian2.PluginSettingTab {
|
|
||||||
constructor(app, plugin) {
|
|
||||||
super(app, plugin);
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
display() {
|
|
||||||
const { containerEl } = this;
|
|
||||||
containerEl.empty();
|
|
||||||
containerEl.createEl("h2", { text: "Settings for latex environments" });
|
|
||||||
new import_obsidian2.Setting(containerEl).setName("Default environment").setDesc("The default environment to insert").addText((text) => text.setPlaceholder("environment").setValue(this.plugin.settings.defaultEnvironment).onChange((value) => __async(this, null, function* () {
|
|
||||||
this.plugin.settings.defaultEnvironment = value;
|
|
||||||
yield this.plugin.saveData(this.plugin.settings);
|
|
||||||
})));
|
|
||||||
new import_obsidian2.Setting(containerEl).setName("Extra environments").setDesc("Environment names to be suggested for completion (one per line)").addTextArea((area) => {
|
|
||||||
area.setValue(this.plugin.settings.customEnvironments.join("\n")).onChange((value) => __async(this, null, function* () {
|
|
||||||
this.plugin.settings.customEnvironments = value.split("\n").map((x) => x.trim()).filter((x) => x.length > 0);
|
|
||||||
yield this.plugin.saveData(this.plugin.settings);
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/actions/action.ts
|
|
||||||
var Action = class {
|
|
||||||
constructor(doc) {
|
|
||||||
this.doc = doc;
|
|
||||||
}
|
|
||||||
suggestName() {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
get needsName() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/environment.ts
|
|
||||||
function newEnvironment(name, cursor, contents = "") {
|
|
||||||
const pad = getPad(contents);
|
|
||||||
return {
|
|
||||||
replaceSelection: `\\begin{${name}}${pad}${contents}${pad}\\end{${name}}`,
|
|
||||||
selection: {
|
|
||||||
from: {
|
|
||||||
ch: 0,
|
|
||||||
line: cursor.line + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function unwrapEnvironment(environment, doc) {
|
|
||||||
return {
|
|
||||||
changes: [
|
|
||||||
{
|
|
||||||
text: trim(environment.contents),
|
|
||||||
from: doc.offsetToPos(environment.begin.from),
|
|
||||||
to: doc.offsetToPos(environment.end.to)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
selection: { from: doc.getCursor() }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function changeEnvironment(environment, doc, name) {
|
|
||||||
const change = {
|
|
||||||
text: `\\begin{${name}}${environment.contents}\\end{${name}}`,
|
|
||||||
from: doc.offsetToPos(environment.begin.from),
|
|
||||||
to: doc.offsetToPos(environment.end.to)
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
changes: [change],
|
|
||||||
selection: { from: doc.getCursor() }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function getPad(text) {
|
|
||||||
if (text.length > 0 && text.match(/^[ \t]*$/) != null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return "\n";
|
|
||||||
}
|
|
||||||
function trim(text) {
|
|
||||||
if (text.length === 0)
|
|
||||||
return text;
|
|
||||||
const start = text.startsWith("\n") ? 1 : 0;
|
|
||||||
const end = text.endsWith("\n") ? text.length - 1 : text.length;
|
|
||||||
return text.slice(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/actions/wrapAction.ts
|
|
||||||
var WrapAction = class extends Action {
|
|
||||||
constructor(doc, addWhitespace = true) {
|
|
||||||
super(doc);
|
|
||||||
this.addWhitespace = addWhitespace;
|
|
||||||
}
|
|
||||||
prepare() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
transaction(envName) {
|
|
||||||
return newEnvironment(envName, this.doc.getCursor(), this.doc.getSelection());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/actions/insertAction.ts
|
|
||||||
var InsertAction = class extends Action {
|
|
||||||
prepare() {
|
|
||||||
if (this.doc.somethingSelected()) {
|
|
||||||
return new WrapAction(this.doc).prepare();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
transaction(envName) {
|
|
||||||
return newEnvironment(envName, this.doc.getCursor());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/actions/changeAction.ts
|
|
||||||
var ChangeAction = class extends Action {
|
|
||||||
suggestName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
prepare() {
|
|
||||||
const cursor = this.doc.posToOffset(this.doc.getCursor());
|
|
||||||
const block = new MathBlock(this.doc.getValue(), cursor);
|
|
||||||
this.current = block.getEnclosingEnvironment(cursor);
|
|
||||||
if (this.current === void 0) {
|
|
||||||
return new WrapAction(this.doc, block.startPosition === block.endPosition);
|
|
||||||
}
|
|
||||||
this.name = this.current.name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
transaction(envName) {
|
|
||||||
if (this.current !== void 0) {
|
|
||||||
return changeEnvironment(this.current, this.doc, envName);
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/actions/deleteAction.ts
|
|
||||||
var DeleteAction = class extends Action {
|
|
||||||
get needsName() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
prepare() {
|
|
||||||
const cursor = this.doc.getCursor();
|
|
||||||
const block = new MathBlock(this.doc.getValue(), this.doc.posToOffset(cursor));
|
|
||||||
this.current = block.getEnclosingEnvironment(this.doc.posToOffset(cursor));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
transaction(_envName) {
|
|
||||||
if (this.current !== void 0) {
|
|
||||||
return unwrapEnvironment(this.current, this.doc);
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/main.ts
|
|
||||||
var LatexEnvironments = class extends import_obsidian3.Plugin {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
this.settings = new LatexEnvironmentsSettings();
|
|
||||||
}
|
|
||||||
onload() {
|
|
||||||
return __async(this, null, function* () {
|
|
||||||
const settings = yield this.loadData();
|
|
||||||
if (settings !== null) {
|
|
||||||
this.settings = ensureSettings(settings);
|
|
||||||
}
|
|
||||||
this.addCommand({
|
|
||||||
id: "insert-latex-env",
|
|
||||||
name: "Insert LaTeX environment",
|
|
||||||
checkCallback: this.mathModeCallback(InsertAction)
|
|
||||||
});
|
|
||||||
this.addCommand({
|
|
||||||
id: "change-latex-env",
|
|
||||||
name: "Change LaTeX environment",
|
|
||||||
checkCallback: this.mathModeCallback(ChangeAction)
|
|
||||||
});
|
|
||||||
this.addCommand({
|
|
||||||
id: "delete-latex-env",
|
|
||||||
name: "Delete LaTeX environment",
|
|
||||||
checkCallback: this.mathModeCallback(DeleteAction)
|
|
||||||
});
|
|
||||||
this.addSettingTab(new LatexEnvironmentsSettingTab(this.app, this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
mathModeCallback(ActionType) {
|
|
||||||
return (checking) => {
|
|
||||||
const leaf = this.app.workspace.activeLeaf;
|
|
||||||
if (leaf.view instanceof import_obsidian3.MarkdownView) {
|
|
||||||
const editor = leaf.view.editor;
|
|
||||||
const cursor = editor.posToOffset(editor.getCursor());
|
|
||||||
if (!MathBlock.isMathMode(cursor, editor)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!checking) {
|
|
||||||
try {
|
|
||||||
const action = new ActionType(editor.getDoc()).prepare();
|
|
||||||
this.withPromptName(editor, action);
|
|
||||||
} catch (e) {
|
|
||||||
new import_obsidian3.Notice(e.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
withPromptName(editor, action) {
|
|
||||||
const call = (envName) => {
|
|
||||||
editor.transaction(action.transaction(envName));
|
|
||||||
editor.focus();
|
|
||||||
};
|
|
||||||
if (action.needsName) {
|
|
||||||
const suggested = action.suggestName();
|
|
||||||
EnvModal.callback(this.app, this.settings, suggested !== void 0 ? suggested : this.settings.defaultEnvironment, call);
|
|
||||||
} else {
|
|
||||||
call("*");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "obsidian-latex-environments",
|
|
||||||
"name": "Latex Environments",
|
|
||||||
"version": "0.3.0",
|
|
||||||
"description": "Allows to quickly insert and change latex environments within math environments.",
|
|
||||||
"author": "Zach Raines",
|
|
||||||
"authorUrl": "https://github.com/raineszm/obsidian-latex-environments",
|
|
||||||
"minAppVersion": "0.11.11",
|
|
||||||
"isDesktopOnly": false
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Not Found
|
|
112
.obsidian/workspace
vendored
112
.obsidian/workspace
vendored
@ -1,112 +0,0 @@
|
|||||||
{
|
|
||||||
"main": {
|
|
||||||
"id": "b5edcffa82772ae7",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "bc097db78015bcba",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Areas/electricity/led.md.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "cabeee83977cea84",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Areas/electricity/led.md.md",
|
|
||||||
"mode": "preview",
|
|
||||||
"source": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "vertical"
|
|
||||||
},
|
|
||||||
"left": {
|
|
||||||
"id": "960bd0ae12708602",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "240323277b6ea277",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "018891641805eabd",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "file-explorer",
|
|
||||||
"state": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "180e37f00da590d0",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "search",
|
|
||||||
"state": {
|
|
||||||
"query": "",
|
|
||||||
"matchingCase": false,
|
|
||||||
"explainSearch": false,
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 300
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
"id": "c57c7700d46038dd",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "aa758b15486a27c3",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "a47b8cf2ccebc103",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "backlink",
|
|
||||||
"state": {
|
|
||||||
"file": "Areas/electricity/led.md.md",
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical",
|
|
||||||
"showSearch": false,
|
|
||||||
"searchQuery": "",
|
|
||||||
"backlinkCollapsed": false,
|
|
||||||
"unlinkedCollapsed": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 300,
|
|
||||||
"collapsed": true
|
|
||||||
},
|
|
||||||
"active": "bc097db78015bcba",
|
|
||||||
"lastOpenFiles": [
|
|
||||||
"Areas/electricity/led.md.md",
|
|
||||||
"Areas/electricity/glossary.md",
|
|
||||||
"Untitled 1.md",
|
|
||||||
"Areas/electricity/basics.md",
|
|
||||||
"Areas/electricity/voltage-dividers.md",
|
|
||||||
"Areas/electricity/index.md",
|
|
||||||
"Areas/electricity/voltage-divider.svg"
|
|
||||||
]
|
|
||||||
}
|
|
0
.trash/assets/ki.md
Normal file
0
.trash/assets/ki.md
Normal file
@ -1,3 +1,3 @@
|
|||||||
# Image of a telephone:
|
# Image of a telephone:
|
||||||
|
|
||||||
![](/api/content/TestArea/test.jpg)
|
![Image of a telephone](test.jpg)
|
||||||
|
8
index.md
8
index.md
@ -3,11 +3,11 @@ private: true
|
|||||||
---
|
---
|
||||||
# JimFX's Personal Wiki
|
# JimFX's Personal Wiki
|
||||||
|
|
||||||
[Ressources](Ressources)
|
[Ressources](Ressources/index.md)
|
||||||
|
|
||||||
[Archive](Archive)
|
[Archive](Archive/index.md)
|
||||||
|
|
||||||
[Projects](Projects)
|
[Projects](Projects/index.md)
|
||||||
|
|
||||||
[Areas](Areas)
|
[Areas](Areas/index.md)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user