├── .gitattributes ├── .github ├── dependabot.yml └── renovate.json ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── jsLinters │ └── eslint.xml ├── misc.xml ├── modules.xml ├── prettier.xml ├── vcs.xml └── zotero-markdb-connect.iml ├── .prettierignore ├── .zenodo.json ├── LICENSE ├── README.md ├── addon ├── bootstrap.js ├── content │ ├── icons │ │ ├── favicon.png │ │ └── favicon@0.5x.png │ ├── preferences.css │ └── preferences.xhtml ├── locale │ └── en-US │ │ ├── addon.ftl │ │ └── preferences.ftl ├── manifest.json └── prefs.js ├── docs └── assets │ └── readme │ ├── ExternalLinkNotificationScreenshot.png │ └── MarkDBConnectScreenshot.png ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── prettier.config.mjs ├── src ├── addon.ts ├── dataGlobals.ts ├── hooks.ts ├── index.ts ├── mdbcTypes.d.ts ├── modules │ ├── create-element.ts │ ├── mdbcConstants.ts │ ├── mdbcLogger.ts │ ├── mdbcParam.ts │ ├── mdbcScan.ts │ ├── mdbcStartupHelpers.ts │ ├── mdbcUX.ts │ ├── monkey-patch.ts │ └── preferenceScript.ts └── utils │ ├── locale.ts │ ├── prefs.ts │ ├── window.ts │ └── ztoolkit.ts ├── tsconfig.base.json ├── tsconfig.dev.json ├── tsconfig.json ├── tsconfig.prod.json ├── tsconfig.repo.json ├── typings ├── global.d.ts ├── mdbc.d.ts ├── prefs.d.ts └── zotero.d.ts ├── update-beta.json ├── update.json ├── update.rdf └── zotero-plugin.config.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | groups: 13 | all-non-major: 14 | update-types: 15 | - "minor" 16 | - "patch" 17 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | ":semanticPrefixChore", 6 | ":prHourlyLimitNone", 7 | ":prConcurrentLimitNone", 8 | ":enableVulnerabilityAlerts", 9 | ":dependencyDashboard", 10 | "group:allNonMajor", 11 | "schedule:weekly" 12 | ], 13 | "labels": ["dependencies"], 14 | "packageRules": [ 15 | { 16 | "matchPackageNames": [ 17 | "zotero-plugin-toolkit", 18 | "zotero-types", 19 | "zotero-plugin-scaffold" 20 | ], 21 | "schedule": ["at any time"], 22 | "automerge": true 23 | } 24 | ], 25 | "git-submodules": { 26 | "enabled": true 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Local config files ### 2 | 3 | 4 | # dot files 5 | .DS_Store 6 | 7 | ### Runtime ### 8 | node_modules/ 9 | 10 | dist/ 11 | 12 | yarn.lock 13 | .DS_Store 14 | 15 | ### Editor directories and files ### 16 | .vscode/ 17 | # .idea/ 18 | 19 | ### Generated files ### 20 | eslint.config.js 21 | 22 | # Node.js 23 | node_modules 24 | pnpm-lock.yaml 25 | yarn.lock 26 | 27 | # TSC 28 | tsconfig.tsbuildinfo 29 | 30 | # Scaffold 31 | .env 32 | .scaffold/ 33 | build/ 34 | logs/ -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # GitHub Copilot persisted chat sessions 7 | /copilot/chatSessions 8 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 81 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jsLinters/eslint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/prettier.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/zotero-markdb-connect.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/.git/ 2 | **/.github/ 3 | **/.vscode/ 4 | **/.idea/ 5 | **/build/ 6 | **/dist/ 7 | **/package-lock.json 8 | **/*.lock 9 | logs 10 | **/node_modules 11 | package-lock.json 12 | yarn.lock 13 | pnpm-lock.yaml 14 | **/*_lintignore* 15 | **/*-lintignore* 16 | -------------------------------------------------------------------------------- /.zenodo.json: -------------------------------------------------------------------------------- 1 | { 2 | "creators": [ 3 | { 4 | "affiliation": "Massachusetts Institute of Technology", 5 | "name": "Houlihan, Dae", 6 | "orcid": "0000-0001-5003-9278" 7 | } 8 | ], 9 | "keywords": ["Zotero", "plugin", "Markdown", "MarkDB-Connect", "Obsidian", "logseq"], 10 | "license": "MIT License", 11 | "upload_type": "software" 12 | } 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sean Dae Houlihan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/daeh/zotero-markdb-connect?style=for-the-badge)](https://github.com/daeh/zotero-markdb-connect/releases/latest) [![GitHub Downloads all releases](https://img.shields.io/github/downloads/daeh/zotero-markdb-connect/total?style=for-the-badge&color=forestgreen)](https://github.com/daeh/zotero-markdb-connect/releases/latest) [![GitHub Downloads (latest release)](https://img.shields.io/github/downloads/daeh/zotero-markdb-connect/latest/total?style=for-the-badge)](https://github.com/daeh/zotero-markdb-connect/releases/latest) 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | # MarkDB-Connect (Zotero Markdown DataBase Connect) 12 | 13 | [![zotero target version](https://img.shields.io/badge/Zotero-7-green?style=flat-square&logo=zotero&logoColor=CC2936)](https://www.zotero.org) [![Using Zotero Plugin Template](https://img.shields.io/badge/Using-Zotero%20Plugin%20Template-blue?style=flat-square&logo=github)](https://github.com/windingwind/zotero-plugin-template) 14 | 15 | - **_Scans your Markdown database and adds a colored tag to associated Zotero items._** 16 | - **_Jump to Markdown notes from the contextual menu of Zotero items._** 17 | - **_Supports various Markdown databases, including [Obsidian](https://obsidian.md), [logseq](https://logseq.com), and [Zettlr](https://www.zettlr.com)_** 18 | - **_[Zotero 7](https://www.zotero.org/support/beta_builds) compatible_** 19 | 20 | ![MarkDBConnectScreenshot](./docs/assets/readme/MarkDBConnectScreenshot.png) 21 | 22 | This is a plugin for [Zotero](https://www.zotero.org), a research source management tool. The _MarkDB-Connect_ plugin searches a user-defined folder for markdown files that include a [Better BibTeX](https://retorque.re/zotero-better-bibtex/) citekey or Zotero-Item-Key, and adds a colored tag to the corresponding Zotero items. 23 | 24 | This plugin was initially designed with the [Obsidian](https://obsidian.md) markdown editor in mind, and was inspired by the [obsidian-citation-plugin](https://github.com/hans/obsidian-citation-plugin) workflow. It offers preliminary support for [logseq](https://logseq.com) and [Zettlr](https://www.zettlr.com). It can be adapted to other databases that store markdown files outside of Zotero, and to other workflows that generate markdown reading notes linked to Zotero items (such as Zotero's `Export Note` feature). 25 | 26 | Please post any bugs, questions, or feature requests in the GitHub repository's [issues](https://github.com/daeh/zotero-markdb-connect/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). 27 | 28 | ## Plugin Functions 29 | 30 | Adds a colored tag to Zotero items for which there are associated reading notes in an external folder. 31 | 32 | Supports multiple markdown files for a single Zotero item. 33 | 34 | Opens an existing markdown note in [Obsidian](https://obsidian.md), [logseq](https://logseq.com), or the system's default markdown note editor (e.g. [Zettlr](https://www.zettlr.com), [Typora](https://typora.io)) from the contextual menu of a Zotero item. 35 | 36 | ## Installation 37 | 38 | - Download the plugin (the `.xpi` file) from the [latest release](https://github.com/daeh/zotero-markdb-connect/releases/latest) 39 | - Open Zotero (version 7.x) 40 | - From `Tools -> Plugins` 41 | - Select `Install Add-on From File...` from the gear icon ⛭ 42 | - Choose the `.xpi` file you downloaded (e.g. `markdb-connect.xpi`) 43 | - Restart Zotero 44 | 45 | > [!NOTE] 46 | > Beginning with `v0.1.0`, _MarkDB-Connect_ will support Zotero 7 exclusively. The last release for Zotero 6 is [`v0.0.27`](https://github.com/daeh/zotero-markdb-connect/releases/tag/v0.0.27). 47 | 48 | ## Setup 49 | 50 | A markdown file can specify which Zotero item it's linked to using either a [Better BibTeX](https://retorque.re/zotero-better-bibtex/) citekey or a Zotero-Item-Key. I recommend using Better BibTeX citekeys when possible. 51 | 52 | 1. Using **Better BibTeX citekeys** to link markdown files to Zotero items. 53 | 54 | - This is recommended if you created the markdown notes with [obsidian-citation-plugin](https://github.com/hans/obsidian-citation-plugin), [BibNotes Formatter](https://github.com/stefanopagliari/bibnotes), or [Obsidian Zotero Integration](https://github.com/mgmeyers/obsidian-zotero-integration). 55 | 56 | - The BetterBibTeX citekey can be taken from the filename, YAML metadata, or body of the markdown note. 57 | 58 | - FYI There's a nice [configuration tutorial](https://publish.obsidian.md/history-notes/Option+-+Link+from+a+Zotero+item+back+to+related+notes+in+Obsidian) detailing a common use case (thanks to Prof. Elena Razlogova). 59 | 60 | 2. Using **Zotero Item Keys** to link markdown files to Zotero items. 61 | 62 | - This is recommended if you created the markdown notes with the `Export Note` feature of Zotero. 63 | 64 | - The markdown note contents should include the Zotero-Item-Key in a consistent format. 65 | 66 | NOTE: multiple markdown files can point to the same Zotero item. But a given markdown file should only be linked to a single Zotero item. A markdown reading note can reference multiple Zotero items throughout the file, but _MarkDB-Connect_ will only link the markdown note to one BetterBibTeX-citekey / Zotero-Item-Key. 67 | 68 | --- 69 | 70 | ### Option 1: Using BetterBibTeX citekeys 71 | 72 | _MarkDB-Connect_ can extract the BetterBibTeX citekey that specifies which Zotero Item a markdown note corresponds to. The BetterBibTeX citekey can be taken from a markdown file's filename, [YAML metadata](https://help.obsidian.md/Advanced+topics/YAML+front+matter), or elsewhere in the file's contents. 73 | 74 |
75 | 76 | configuration details 77 | 78 | - In Zotero's Settings, click the `MarkDB-Connect` preference pane. 79 | 80 | - Specify the location of the folder that contains your markdown reading notes (e.g. `/Users/me/Documents/ObsVault/ReadingNotes/`). The _MarkDB-Connect_ plugin will recursively search this path for markdown files. 81 | 82 | - By default, _MarkDB-Connect_ expects that the filenames of your markdown reading note files begin with `@mycitekey` but can include extra information after it (e.g. a reading note with the BetterBibTeX citekey `shepard1987science` could have the filename `@shepard1987science.md` or `@shepard1987science Toward a universal law of generalization for psychological science.md`). 83 | 84 | - If your BetterBibTeX citekeys contain certain special characters (e.g. `:`, `/`), you will need to extract the citekeys from the markdown file's contents rather than its filename. 85 | 86 | - If the default does not match your use case, you can specify how to extract BetterBibTeX citekeys. 87 | 88 | - **A. filename** - Select `Custom File Filter` and define a RegExp with a single capturing group. 89 | 90 | - E.g. the default is `^@(\S+).*\.md$`, which looks for files beginning with `@` and uses the first word as the BetterBibTeX citekey. 91 | 92 | - **B. metadata** - Select `BetterBibTeX citekey - taken from YAML metadata` and specify a keyword from the notes' YAML frontmatter (here's an [example](#example-markdown-note)). 93 | 94 | - For info on metadata syntax, see [YAML front matter](https://help.obsidian.md/Advanced+topics/YAML+front+matter). 95 | 96 | - **C. contents** - Select `BetterBibTeX citekey - captured with custom RegExp` and define a RegExp with a single capturing group to return exactly 1 match per file. 97 | 98 | - Run the synchronization function from `Tools -> MarkDB-Connect Sync Tags`. 99 | 100 | - This will add a tag (`ObsCite`) to every Zotero item for which there exists a reading note in the external folder you specified. 101 | 102 | - In the `Tags` plane of Zotero, right-click on the `ObsCite` tag and assign it a color, which will mark the tagged items in the preview plane of Zotero. (In the screenshot above, Zotero items associated with reading notes are marked with a 🟦 blue tag.) 103 | 104 |
105 | 106 | --- 107 | 108 | ### Option 2: Using Zotero Item Keys 109 | 110 | _MarkDB-Connect_ can extract the Zotero-Item-Key that specifies which Zotero Item a markdown note corresponds to. The Zotero-Item-Key is taken from the markdown file contents using a custom RegExp pattern. 111 | 112 | Zotero automatically generates Item Keys, they take the form of `ABCD1234`, as in `zotero://select/library/items/ABCD1234`. NB this is not the same as the BetterBibTeX citekey you assigned an item (e.g. `mycitekey` in `zotero://select/items/@mycitekey`). 113 | 114 |
115 | 116 | configuration details 117 | 118 | - In Zotero's Settings, click the `MarkDB-Connect` preference pane. 119 | 120 | - Specify the location of the folder that contains your markdown reading notes (e.g. `/Users/me/Documents/ObsVault/ReadingNotes/`). The _MarkDB-Connect_ plugin will recursively search this path for markdown files. 121 | 122 | - The default behavior is to search for markdown files beginning with `@`. 123 | 124 | - Alternatively, you can define a custom RegExp pattern to match your reading note files. 125 | 126 | - Select the `Match Markdown Files to Zotero Items Using:` `Zotero-Item-Key - captured with custom RegExp` option. 127 | 128 | - Specify a RegExp pattern to extract the Zotero-Item-Key from the markdown contents. 129 | 130 | E.g. if your note has the line 131 | 132 | `- local:: [local zotero](zotero://select/library/items/GZ9DQ2AM)` 133 | 134 | you could extract the Zotero key (`GZ9DQ2AM`) using this RegExp pattern: 135 | 136 | `^- local::.+\/items\/(\w+)\)` 137 | 138 | - Run the synchronization function from `Tools -> MarkDB-Connect Sync Tags`. 139 | 140 | - This will add a tag (`ObsCite`) to every Zotero item for which there exists a reading note in the external folder you specified. 141 | 142 | - In the `Tags` plane of Zotero, right-click on the `ObsCite` tag and assign it a color, which will mark the tagged items in the preview plane of Zotero. (In the screenshot above, Zotero items associated with reading notes are marked with a 🟦 blue tag.) 143 | 144 |
145 | 146 | --- 147 | 148 | ## Example Markdown Note 149 | 150 | In this example markdown note (`@saxe2017emobtom.md`), _MarkDB-Connect_ will use the [YAML metadata](https://help.obsidian.md/Advanced+topics/YAML+front+matter) keyword `citekey` to find the BetterBibTeX citekey (`saxe2017emobtom`) that determines which Zotero item to associate with the markdown file. Notice that the markdown file can include other BetterBibTeX citekeys and Zotero-Item-Keys, which are ignored by the plugin. 151 | 152 | ```markdown 153 | --- 154 | citekey: saxe2017emobtom 155 | zoterouri: zotero://select/library/items/IACZMXU4 156 | bbturi: zotero://select/items/@saxe2017emobtom 157 | doi: 10.1016/j.copsyc.2017.04.019 158 | --- 159 | 160 | # @saxe2017emobtom 161 | 162 | **Formalizing emotion concepts within a Bayesian model of theory of mind** 163 | (2017) _Current Opinion in Psychology_ 164 | [Open in Zotero](zotero://select/library/items/IACZMXU4) 165 | 166 | The body of notes can include references to other Zotero items. 167 | The _MarkDB-Connect_ plugin will only link this file to one Zotero item 168 | (in this case, it will use the value of the `citekey` property). 169 | 170 | Here are links to other papers: 171 | 172 | - This one uses [a Zotero URI](zotero://select/library/items/4RJ97IFL) 173 | 174 | - This one uses [a BetterBibTeX URI](zotero://select/items/@anzellotti2021opaque) 175 | 176 | - This one uses an Obsidian wiki link: [[@cusimano2018cogsci]] 177 | ``` 178 | 179 |
180 | 181 | Example Templates 182 | 183 | Below are example templates for various Obsidian plugins 184 | 185 | #### Template for [obsidian-citation-plugin](https://github.com/hans/obsidian-citation-plugin) 186 | 187 | ```md 188 | --- 189 | citekey: "{{citekey}}" 190 | title: "{{title}}" 191 | year: {{year}} 192 | authors: [{{authorString}}] 193 | {{#if containerTitle~}} publication: "{{containerTitle}}" {{~else~}} {{~/if}} 194 | {{#if DOI~}} doi: "{{DOI}}" {{~else~}} {{~/if}} 195 | aliases: ["@{{citekey}}", "@{{citekey}} {{title}}"] 196 | tags: 197 | - readingNote 198 | --- 199 | 200 | # @{{citekey}} 201 | 202 | **{{title}}** 203 | {{authorString}} 204 | {{#if year~}} ({{year}}) {{~else~}} {{~/if}} {{~#if containerTitle}} _{{containerTitle~}}_ {{~else~}} {{~/if}} 205 | [Open in Zotero]({{zoteroSelectURI}}) 206 | ``` 207 | 208 | #### Template for ZotLit 209 | 210 | Make a file (e.g. `zotlit-properties.eta.md`) with the following contents, and point to that file in ZotLit settings: `Template` > `Note Properties`. 211 | 212 | ```eta 213 | citekey: "<%= it.citekey %>" 214 | title: "<%= it.title %>" 215 | <% if (it.date) { %>year: <%= it.date %><% } %> 216 | authors: [<%= it.authors.map(v => v.firstName v.lastName) %>] 217 | <% if (it.publicationTitle) { %>publication: "<%= it.publicationTitle %>"<% } %> 218 | <% if (it.DOI) { %>doi: "<%= it.DOI %>"<% } %> 219 | aliases: ["@<%= it.citekey %>", "@<%= it.citekey %> <%= it.title %>"] 220 | tags: 221 | - readingNote 222 | ``` 223 | 224 |
225 | 226 | ## Suppressing the Zotero security notification 227 | 228 | Recent builds of Zotero have introduced a security notification for external links. At present, Zotero does not remember the user's link preferences, so this alert is shown every time an application-specific URI is launched. You can suppress this warning by setting `security.external_protocol_requires_permission` to `false` in Zotero's advanced configuration. 229 | 230 | ![Zotero Security Notification](./docs/assets/readme/ExternalLinkNotificationScreenshot.png) 231 | 232 |
233 | 234 | Instructions for modifying Zotero's advanced config 235 | 236 | 1. Open Zotero Settings 237 | 2. Click the "Advanced" tab 238 | 3. Click the "Config Editor" button 239 | 4. Click the "Accept Risk and Continue" button 240 | 5. Search for `security.external_protocol_requires_permission` 241 | 6. Double click the `security.external_protocol_requires_permission` item to toggle its value to `false` 242 | 243 |
244 | 245 | ## Related Projects 246 | 247 | - [obsidian-citation-plugin](https://github.com/hans/obsidian-citation-plugin) by hans 248 | - Obsidian plugin that integrates your Zotero database with Obsidian. 249 | - [BibNotes Formatter](https://github.com/stefanopagliari/bibnotes) by stefanopagliari 250 | - Obsidian plugin to facilitate exporting annotations from Zotero into Obsidian. 251 | - [Obsidian Zotero Integration](https://github.com/mgmeyers/obsidian-zotero-integration) by mgmeyers 252 | - Obsidian plugin to facilitate exporting annotations from Zotero into Obsidian. 253 | - [Zotero 6 'Export Notes' feature](https://forums.zotero.org/discussion/93521/available-for-beta-testing-markdown-export-of-notes/p1) by Zotero 254 | - Zotero 6 beta feature to export notes and annotations from Zotero items as markdown files. 255 | - [Zotero to Markdown](https://github.com/e-alizadeh/Zotero2md) by e-alizadeh 256 | - Python library to export annotations and notes from Zotero items as markdown files. 257 | - [Zotero Better Notes](https://github.com/windingwind/zotero-better-notes) by windingwind 258 | - A Zotero plugin for note management. 259 | - [Logseq Citations Plugin](https://github.com/sawhney17/logseq-citation-manager) by sawhney17 260 | - Logseq plugin that integrates your Zotero database with Logseq. 261 | 262 | 264 | 265 | ## Notes 266 | 267 | [GitHub](https://github.com/daeh/zotero-markdb-connect): Source code repository 268 | 269 | This extension uses the [zotero-plugin-template](https://github.com/windingwind/zotero-plugin-template). 270 | 271 | ## License 272 | 273 | Distributed under the MIT License. 274 | 275 | ## Author 276 | 277 | [![Personal Website](https://img.shields.io/badge/personal%20website-daeh.info-orange?style=for-the-badge)](https://daeh.info) [![BlueSky](https://img.shields.io/badge/bsky-@dae.bsky.social-skyblue?style=for-the-badge&logo=bluesky)](https://bsky.app/profile/dae.bsky.social) 278 | -------------------------------------------------------------------------------- /addon/bootstrap.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 3 | /** 4 | * Most of this code is from Zotero team's official Make It Red example[1] 5 | * or the Zotero 7 documentation[2]. 6 | * [1] https://github.com/zotero/make-it-red 7 | * [2] https://www.zotero.org/support/dev/zotero_7_for_developers 8 | */ 9 | 10 | var chromeHandle 11 | 12 | function install(data, reason) {} 13 | 14 | async function startup({ id, version, resourceURI, rootURI }, reason) { 15 | await Zotero.initializationPromise 16 | 17 | // String 'rootURI' introduced in Zotero 7 18 | if (!rootURI) { 19 | rootURI = resourceURI.spec 20 | } 21 | 22 | var aomStartup = Components.classes['@mozilla.org/addons/addon-manager-startup;1'].getService( 23 | Components.interfaces.amIAddonManagerStartup, 24 | ) 25 | var manifestURI = Services.io.newURI(rootURI + 'manifest.json') 26 | chromeHandle = aomStartup.registerChrome(manifestURI, [['content', '__addonRef__', rootURI + 'content/']]) 27 | 28 | /** 29 | * Global variables for plugin code. 30 | * The `_globalThis` is the global root variable of the plugin sandbox environment 31 | * and all child variables assigned to it is globally accessible. 32 | * See `src/index.ts` for details. 33 | */ 34 | const ctx = { 35 | rootURI, 36 | } 37 | ctx._globalThis = ctx 38 | 39 | Services.scriptloader.loadSubScript(`${rootURI}/content/scripts/__addonRef__.js`, ctx) 40 | Zotero.__addonInstance__.hooks.onStartup() 41 | } 42 | 43 | async function onMainWindowLoad({ window }, reason) { 44 | Zotero.__addonInstance__?.hooks.onMainWindowLoad(window) 45 | } 46 | 47 | async function onMainWindowUnload({ window }, reason) { 48 | Zotero.__addonInstance__?.hooks.onMainWindowUnload(window) 49 | } 50 | 51 | function shutdown({ id, version, resourceURI, rootURI }, reason) { 52 | if (reason === APP_SHUTDOWN) { 53 | return 54 | } 55 | 56 | if (typeof Zotero === 'undefined') { 57 | Zotero = Components.classes['@zotero.org/Zotero;1'].getService(Components.interfaces.nsISupports).wrappedJSObject 58 | } 59 | Zotero.__addonInstance__?.hooks.onShutdown() 60 | 61 | Cc['@mozilla.org/intl/stringbundle;1'].getService(Components.interfaces.nsIStringBundleService).flushBundles() 62 | 63 | Cu.unload(`${rootURI}/content/scripts/__addonRef__.js`) 64 | 65 | if (chromeHandle) { 66 | chromeHandle.destruct() 67 | chromeHandle = null 68 | } 69 | } 70 | 71 | function uninstall(data, reason) {} 72 | -------------------------------------------------------------------------------- /addon/content/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daeh/zotero-markdb-connect/1db3ee2faad330a85f8eb1ec6c359333a4d68a30/addon/content/icons/favicon.png -------------------------------------------------------------------------------- /addon/content/icons/favicon@0.5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daeh/zotero-markdb-connect/1db3ee2faad330a85f8eb1ec6c359333a4d68a30/addon/content/icons/favicon@0.5x.png -------------------------------------------------------------------------------- /addon/content/preferences.css: -------------------------------------------------------------------------------- 1 | groupbox.mdbc-pref-section-box { 2 | border: 2px solid black; 3 | border-radius: 10px; 4 | padding-bottom: 10px; 5 | width: 98%; 6 | min-width: 300px; 7 | /*max-width: 100%;*/ 8 | } 9 | 10 | hbox.mdbc-pref-hbox-indent { 11 | display: inline-flex; 12 | flex-wrap: nowrap; /* Prevents flex items from wrapping */ 13 | overflow: visible; /* Makes overflow content visible */ 14 | align-items: center; /* Vertically centers the items in the line */ 15 | justify-content: space-between; /* Puts space before the first and after the last item, but not between items */ 16 | /*display: -moz-inline-box;*/ 17 | /*display: -webkit-inline-box;*/ 18 | padding-left: 10px; 19 | width: 100%; 20 | white-space: pre; 21 | max-width: 100%; 22 | } 23 | 24 | label.mdbc-pref-label-hone { 25 | font-size: 18px; 26 | font-weight: 700; 27 | text-align: center; 28 | } 29 | 30 | caption.mdbc-pref-section-title { 31 | padding: 15px 0 5px 10px; 32 | font-size: 18px; 33 | font-weight: 700; 34 | } 35 | 36 | label.mdbc-pref-subsection-title { 37 | padding: 15px 0 1px 10px; 38 | font-size: 16px; 39 | font-weight: 500; 40 | } 41 | 42 | description.mdbc-pref-description-indent { 43 | padding-left: 10px; 44 | } 45 | 46 | input.mdbc-pref-textbox-flex1 { 47 | -moz-box-flex: 1; 48 | } 49 | 50 | /*input.mdbc-pref-textbox-fullwidth {*/ 51 | /* width: 100%;*/ 52 | /*}*/ 53 | 54 | input[type='text'].mdbc-pref-textbox-partialwidth { 55 | min-width: 80px; 56 | width: 100px; 57 | /*-moz-box-flex: 1;*/ 58 | /*width: 100%;*/ 59 | flex-grow: 3; /* Make the input expand */ 60 | margin-left: 0; 61 | margin-right: 0; 62 | font-family: monospace; 63 | } 64 | 65 | radio.mdbc-pref-radio-main { 66 | padding: 18px 0 1px 2px; 67 | font-size: 16px; 68 | font-weight: 700; 69 | } 70 | 71 | .mdbc-pref-explication-minor { 72 | font-size: 11px; 73 | } 74 | 75 | .mdbc-pref-text-center { 76 | text-align: center; 77 | } 78 | 79 | .mdbc-pref-width-full { 80 | /*width: 100%;*/ 81 | width: 600px; 82 | } 83 | 84 | hr.mdbc-pref-hr { 85 | border: 2px solid darkslategrey; 86 | margin-top: 10px; 87 | opacity: 20%; 88 | border-radius: 5px; 89 | } 90 | 91 | div.mdbc-pref-options-div { 92 | background-color: #e5e5e5; 93 | border: 2px solid rgba(0, 0, 0, 0.5); 94 | padding: 5px; 95 | margin-left: 5px; 96 | margin-right: 5px; 97 | border-radius: 10px; 98 | /*width: 100%;*/ 99 | width: 94%; 100 | /*max-width: fit-content;*/ 101 | } 102 | 103 | span.mdbc-pref-options-code-span { 104 | font-family: monospace; 105 | font-weight: 600; 106 | } 107 | span.mdbc-pref-options-span-first { 108 | text-align: left; 109 | } 110 | span.mdbc-pref-options-span-left { 111 | padding-left: 4px; 112 | text-align: right; 113 | padding-right: 0; 114 | margin-right: 0; 115 | font-size: 13px; 116 | } 117 | span.mdbc-pref-options-span-right { 118 | flex-grow: 1; 119 | text-align: left; 120 | padding-left: 0; 121 | margin-left: 0; 122 | font-size: 13px; 123 | } 124 | code.mdbc-pref-code-indent { 125 | padding-left: 10px; 126 | } 127 | 128 | /*div.testtt3 {*/ 129 | /* background-color: #e5e5e5;*/ 130 | /* border: 2px solid rgba(1, 0, 0, 0.5);*/ 131 | /* padding: 5px;*/ 132 | /* margin-left: 5px;*/ 133 | /* margin-right: 5px;*/ 134 | /* border-radius: 10px;*/ 135 | /* !*width: 100%;*!*/ 136 | /* width: 600px;*/ 137 | /* !*max-width: fit-content;*!*/ 138 | /*}*/ 139 | 140 | /* Dark theme font color */ 141 | @media (prefers-color-scheme: dark) { 142 | div.mdbc-pref-options-div { 143 | background-color: #212121; 144 | border: 2px solid rgba(255, 255, 255, 0.5); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /addon/content/preferences.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 |