├── .npmrc ├── styles.css ├── versions.json ├── manifest.json ├── .gitignore ├── tsconfig.json ├── version-bump.mjs ├── package.json ├── .github └── FUNDING.yml ├── LICENSE ├── esbuild.config.mjs ├── README.md └── main.ts /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* This plugin doesn't make use of special CSS. */ 2 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.0": "0.9.7", 3 | "1.0.1": "0.12.0" 4 | } 5 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-table-to-csv-exporter", 3 | "name": "Table to CSV Exporter", 4 | "version": "0.1.4", 5 | "minAppVersion": "0.14.6", 6 | "description": "This plugin allows for exporting tables from a pane in reading mode into CSV files.", 7 | "author": "Stefan Wolfrum", 8 | "authorUrl": "https://twitter.com/metawops", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # vscode 2 | .vscode 3 | .editorconfig 4 | .eslintignore 5 | .eslintrc 6 | 7 | # Intellij 8 | *.iml 9 | .idea 10 | 11 | # npm 12 | node_modules 13 | 14 | # Don't include the compiled main.js file in the repo. 15 | # They should be uploaded to GitHub releases instead. 16 | main.js 17 | 18 | # Exclude sourcemaps 19 | *.map 20 | 21 | # obsidian 22 | data.json 23 | 24 | # Exclude macOS Finder (System Explorer) View States 25 | .DS_Store 26 | obsidian-table-to-csv-exporter.code-workspace 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "module": "ESNext", 7 | "target": "ES6", 8 | "allowJs": true, 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "importHelpers": true, 12 | "isolatedModules": true, 13 | "lib": [ 14 | "DOM", 15 | "ES5", 16 | "ES6", 17 | "ES7" 18 | ] 19 | }, 20 | "include": [ 21 | "**/*.ts" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /version-bump.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from "fs"; 2 | 3 | const targetVersion = process.env.npm_package_version; 4 | 5 | // read minAppVersion from manifest.json and bump version to target version 6 | let manifest = JSON.parse(readFileSync("manifest.json", "utf8")); 7 | const { minAppVersion } = manifest; 8 | manifest.version = targetVersion; 9 | writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); 10 | 11 | // update versions.json with target version and minAppVersion from manifest.json 12 | let versions = JSON.parse(readFileSync("versions.json", "utf8")); 13 | versions[targetVersion] = minAppVersion; 14 | writeFileSync("versions.json", JSON.stringify(versions, null, "\t")); 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-table-to-csv-exporter", 3 | "version": "0.1.4", 4 | "description": "This plugin allows to export tables in a preview pane to be exported to CSV files.", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "node esbuild.config.mjs", 8 | "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", 9 | "version": "node version-bump.mjs && git add manifest.json versions.json" 10 | }, 11 | "keywords": [], 12 | "author": "Stefan Wolfrum", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/node": "^16.11.6", 16 | "@typescript-eslint/eslint-plugin": "^5.2.0", 17 | "@typescript-eslint/parser": "^5.2.0", 18 | "builtin-modules": "^3.2.0", 19 | "esbuild": "0.13.12", 20 | "obsidian": "latest", 21 | "tslib": "2.3.1", 22 | "typescript": "4.4.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: metawops # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Stefan Wolfrum 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 | -------------------------------------------------------------------------------- /esbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import process from "process"; 3 | import builtins from 'builtin-modules' 4 | 5 | const banner = 6 | `/* 7 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 8 | if you want to view the source, please visit the github repository of this plugin 9 | */ 10 | `; 11 | 12 | const prod = (process.argv[2] === 'production'); 13 | 14 | esbuild.build({ 15 | banner: { 16 | js: banner, 17 | }, 18 | entryPoints: ['main.ts'], 19 | bundle: true, 20 | external: [ 21 | 'obsidian', 22 | 'electron', 23 | '@codemirror/autocomplete', 24 | '@codemirror/closebrackets', 25 | '@codemirror/collab', 26 | '@codemirror/commands', 27 | '@codemirror/comment', 28 | '@codemirror/fold', 29 | '@codemirror/gutter', 30 | '@codemirror/highlight', 31 | '@codemirror/history', 32 | '@codemirror/language', 33 | '@codemirror/lint', 34 | '@codemirror/matchbrackets', 35 | '@codemirror/panel', 36 | '@codemirror/rangeset', 37 | '@codemirror/rectangular-selection', 38 | '@codemirror/search', 39 | '@codemirror/state', 40 | '@codemirror/stream-parser', 41 | '@codemirror/text', 42 | '@codemirror/tooltip', 43 | '@codemirror/view', 44 | ...builtins], 45 | format: 'cjs', 46 | watch: !prod, 47 | target: 'es2016', 48 | logLevel: "info", 49 | sourcemap: prod ? false : 'inline', 50 | treeShaking: true, 51 | outfile: 'main.js', 52 | }).catch(() => process.exit(1)); 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://badgen.net/github/release/metawops/obsidian-table-to-csv-export?icon=github) ![](https://badgen.net/github/assets-dl/metawops/obsidian-table-to-csv-export?icon=github) ![](https://badgen.net/github/stars/metawops/obsidian-table-to-csv-export?icon=github&color=cyan) ![](https://badgen.net/github/watchers/metawops/obsidian-table-to-csv-export?icon=github&color=cyan) ![](https://badgen.net/github/license/metawops/obsidian-table-to-csv-export?icon=github&color=grey) 2 | 3 | ![](https://badgen.net/github/closed-issues/metawops/obsidian-table-to-csv-export?icon=github) ![](https://badgen.net/github/open-issues/metawops/obsidian-table-to-csv-export?icon=github) 4 | 5 | 6 | # Obsidian Plugin "Table to CSV Exporter" 7 | 8 | This is my very first attempt in writing a plugin for [Obsidian](https://obsidian.md). I didn't even know TypeScript before (but JavaScript). 9 | 10 | ## What does it do? 11 | 12 | The purpose of this plugin is to be able to export table data from a pane in reading mode into a CSV file. 13 | 14 | Background: The fabulous [Dataview](https://github.com/blacksmithgu/obsidian-dataview) plugin for Obsidian allows to dynamically create tables from an SQL-like query over your notes' metadata. 15 | I wanted to be able to further use this created data in external applications, like MS Power BI, to create visualizations of that data. 16 | But the plugin can export any table into a CSV file, even those you "hard-coded" in Markdown (if that makes sense for you) or those that were created by some other plugin. 17 | 18 | ## Settings 19 | 20 | My plugin allows you to configure a few things in its settings: 21 | 22 | * **The base filename of the CSV file** 23 | 24 | This is the first part of the filename of the CSV file you're about to save. 25 | 26 | **Default**: `table-export` 27 | 28 | * **A file number addition** 29 | 30 | This gets added to the base filename (after a hyphen). After this, the extension `.csv` is added. 31 | This number gets incremented by one after each succesful export and resetted to 001 after reaching 999. 32 | Normally you won't need to interfere with this in the settings but you can change it if you want. 33 | **But be careful!** Don't mess with this. Don't change this to text or something different than numbers. And stay in the ### scheme (three ciphers max., leading zeroes). 34 | It may become neccessary to either change this number manually or to delete/rename/move files out of your vault folder. 35 | No worries, though: the plugin never overwrites any files and warns you if a file already exists. 36 | 37 | **Default**: `001` 38 | 39 | * **The separation character** 40 | 41 | Here you can select the character that separates the data fields in the CSV file. The dropdown box contains the usual suspects like comma, semicolon and tab. But there are some unusual choices as well. 42 | 43 | **Default**: `;` 44 | 45 | * **Quote data** 46 | 47 | If you want the data cells in the CSV file to be enclosed in quotation marks you can choose to do so here. In the dropdown box you can choose between either double quotation marks (`"`), single quotation marks (`'`) or not to quote data at all. 48 | 49 | **Default**: no quoting 50 | 51 | * **Handling of CR/LF in data** 52 | 53 | In some rare cases you might have return (CR) or linefeed (LF) characters inside of data fields/cells. This will break the CSV file. With this setting you can select how you want to handle these characters. You can either simply strip them, replace them with a single space character or replace them with the fixed string `[CR]`so that you later can still see that there once _was_ some kind of return character in your data. 54 | 55 | **Default**: Replace all CR & LF characters with one space 56 | 57 | * **Copy to clipboard, too** 58 | 59 | Optionally you can copy the CSV string to the clipboard, too. 60 | 61 | **Default**: `off` 62 | 63 | ## Usage 64 | 65 | The plugin adds a new command: "Export table to CSV file". This will only work when your currently active pane is in reading mode. When the command is executed a `.csv` file is written according to the settings in your vault's main folder. This CSV file contains the data of the *first* table in the reading mode of the note. 66 | 67 | The plugin works on mobile, too. (Tested on iPadOS only, though.) 68 | 69 | ## Current limitations 70 | 71 | Of course, there's always room for improvement. **As of version 0.1.4, there are the following limitations/restrictions**: 72 | 73 | * The plugin currently exports only the first table that it finds in the reading mode of a note. 74 | * The plugin saves the CSV file directly into you vault's main folder. A feature to select another folder inside your vault will be added later. 75 | 76 | ## Thanks 77 | 78 | I'd like to thank several people here. Without them this plugin wouldn't have come to live. 79 | 80 | * [Edmund Gröpl](https://twitter.com/groepl) – for bringing up the problem at all and his encouragement over all the years. 81 | * [Marcus Olsson](https://github.com/marcusolsson) – for starting the [Obsidian Plugin Developer Docs](https://marcus.se.net/obsidian-plugin-docs/) project which I highly recommend, especially for beginners. He's on Twitter, too: [@marcusolsson](https://twitter.com/marcusolsson) 82 | * [Johannes Theiner](https://github.com/joethei) – a very kind and helpful user over at the official Obsidian Discord server. I met him in the `#plugin-dev` channel and his answers to my questions were very helpful. He's also on Twitter: [@joethei](https://twitter.com/joethei) 83 | 84 | ## Contact 85 | 86 | Please leave feedback here in the GitHub discussions or file a new issue if you found a bug or have a feature request. 87 | You can reach me via Twitter, too: 88 | [![](https://badgen.net/twitter/follow/metawops?icon=twitter)](https://twitter.com/metawops) 89 | 90 | 91 | ## Sponsoring 92 | 93 | If this plugin adds value for you and you would like to help support continued development, please consider sponsoring this repository via [GitHub Sponsors](https://github.com/sponsors/metawops), [PayPal](https://paypal.me/stefanwolfrum) or [Buy me a coffee](https://www.buymeacoffee.com/metawops). 94 | 95 | [![](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee&emoji=&slug=metawops&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff)](https://www.buymeacoffee.com/metawops) 96 | 97 | Made with ❤️ in Bonn, Germany. 98 | -------------------------------------------------------------------------------- /main.ts: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------------------- 2 | // File : main.ts 3 | // Author : Stefan Wolfrum (@metawops) 4 | // Date : 2022-05-27 5 | // Last Update: 2022-06-12 6 | // Description: Implementation of my very first Obsidian plugin. 7 | // It allows to export rendered HTML tables (i.e. from a pane in reading mode) 8 | // to be exported to a CSV file and optionally to the clipboard, too. 9 | // Purely based on the Obsidian sample plugin. 10 | // ---------------------------------------------------------------------------------------- 11 | 12 | import { App, MarkdownView, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian'; 13 | 14 | interface Table2CSVSettings { 15 | exportPath: string; 16 | baseFilename: string; 17 | fileNumber: string; 18 | sepChar: string; 19 | quoteDataChar: string; 20 | saveToClipboardToo: boolean; 21 | removeCRLF: string; 22 | } 23 | 24 | const DEFAULT_SETTINGS: Table2CSVSettings = { 25 | exportPath: './', 26 | baseFilename: 'table-export', 27 | fileNumber: '001', 28 | sepChar: 'sepChar-semicolon', 29 | quoteDataChar: 'quoteChar-noQuote', 30 | saveToClipboardToo: false, 31 | removeCRLF: 'removeCRLF-space' 32 | } 33 | 34 | export default class Table2CSVPlugin extends Plugin { 35 | settings: Table2CSVSettings; 36 | 37 | async onload() { 38 | 39 | await this.loadSettings(); 40 | 41 | this.addCommand({ 42 | id: 'obsidian-table-to-csv-exporter', 43 | name: 'Export table to CSV file', 44 | checkCallback: (checking: boolean) => { 45 | 46 | const view = this.app.workspace.getActiveViewOfType(MarkdownView); 47 | 48 | if (view) { 49 | if (!checking) { 50 | // Here we can actually start with our work 51 | const viewMode = view.getMode(); 52 | if (viewMode=="preview") { 53 | // Now convert the tables 54 | const csvString = htmlToCSV(view.previewMode.containerEl, this.settings.sepChar, this.settings.quoteDataChar, this.settings.removeCRLF); 55 | 56 | // If csvString is not empty, create file: 57 | if (csvString.length > 0) { 58 | const filename = `${this.settings.baseFilename}-${this.settings.fileNumber}.csv`; 59 | this.app.vault.create(filename, csvString) 60 | .then( () => { 61 | // increment the file number addition string 62 | // first, convert the current string to a number: 63 | let fn: number = +this.settings.fileNumber; 64 | // then increment the number: 65 | fn++; 66 | // don't allow more that 999; restart with 001 in that case: 67 | if (fn==1000) fn = 1; 68 | // convert the number to a string again: 69 | let newFileNumberString: string = fn + ""; 70 | // add leading zeroes to the string: 71 | while (newFileNumberString.length < 3) newFileNumberString = "0" + newFileNumberString; 72 | this.settings.fileNumber = newFileNumberString; 73 | if (this.settings.saveToClipboardToo) { 74 | navigator.clipboard 75 | .writeText(csvString) 76 | .then(() => { 77 | new Notice(`The file ${filename} was successfully created in your vault. The contents was also copied to the clipboard.`); 78 | }) 79 | .catch((err) => { 80 | new Notice('There was an error with copying the contents to the clipboard.'); 81 | }); 82 | 83 | } else { 84 | new Notice(`The file ${filename} was successfully created in your vault.`) 85 | } 86 | }) 87 | 88 | .catch( (error) => { 89 | const errorMessage = `Error: ${error.message}`; 90 | new Notice(errorMessage); 91 | }) 92 | } 93 | else { 94 | new Notice(`No table was found. No CSV file was written.`); 95 | } 96 | 97 | } 98 | else { 99 | new Notice('This command only works on panes in reading mode! – No CSV files were written.'); 100 | } 101 | } 102 | 103 | return true; 104 | } 105 | 106 | return false; 107 | } 108 | }); 109 | 110 | 111 | // This adds a settings tab so the user can configure various aspects of the plugin 112 | this.addSettingTab(new Table2CSVSettingTab(this.app, this)); 113 | 114 | console.log(`Table to CSV plugin: Version ${this.manifest.version} loaded.`); 115 | } 116 | 117 | onunload() { 118 | } 119 | 120 | async loadSettings() { 121 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); 122 | } 123 | 124 | async saveSettings() { 125 | await this.saveData(this.settings); 126 | } 127 | } 128 | 129 | 130 | function htmlToCSV(html: HTMLElement, sepMode: string, quoteChar: string, removeCRLF: string) { 131 | var data = []; 132 | var table = html.querySelector("table"); 133 | //console.log(`htmlToCSV::table: ${table}`); 134 | 135 | if (table) { 136 | var rows = table.rows; 137 | //console.log(`htmlToCSV::rows: ${rows}`); 138 | for (var i = 0; i < rows.length; i++) { 139 | var row = [], cols = rows[i].querySelectorAll("td, th"); 140 | 141 | for (var j = 0; j < cols.length; j++) { 142 | var cellContent = (cols[j] as HTMLElement).innerText; 143 | 144 | // handle the optional replacement of CR/LF characters: 145 | if (removeCRLF=='removeCRLF-clear') { 146 | cellContent = cellContent.replace(/(\r\n|\n|\r)/gm, ""); 147 | } else if (removeCRLF=='removeCRLF-space') { 148 | cellContent = cellContent.replace(/(\r\n|\n|\r)/gm, " "); 149 | } else if (removeCRLF=='removeCRLF-string1') { 150 | cellContent = cellContent.replace(/(\r\n|\n|\r)/gm, "[CR]"); 151 | } 152 | 153 | // handle the quoting of data cells: 154 | // for now it's just the hard-coded character " 155 | if (quoteChar=='quoteChar-doubleQuotes') { 156 | cellContent = '"' + cellContent + '"'; 157 | } else if (quoteChar=='quoteChar-singleQuotes') { 158 | cellContent = "'" + cellContent + "'"; 159 | } 160 | row.push(cellContent); 161 | } 162 | 163 | var sepChar = ';'; 164 | switch(sepMode) { 165 | case 'sepChar-semicolon': 166 | sepChar = ';'; 167 | break; 168 | case 'sepChar-comma': 169 | sepChar = ','; 170 | break; 171 | case 'sepChar-tab': 172 | sepChar = '\t'; 173 | break; 174 | case 'sepChar-pipe': 175 | sepChar = '|'; 176 | break; 177 | case 'sepChar-tilde': 178 | sepChar = '~'; 179 | break; 180 | case 'sepChar-caret': 181 | sepChar = '^'; 182 | break; 183 | case 'sepChar-colon': 184 | sepChar = ':'; 185 | break; 186 | } 187 | data.push(row.join(sepChar)); 188 | } 189 | } 190 | //console.log(`htmlToCSV::data.length: ${data.length}`); 191 | if (data.length > 0) 192 | return data.join("\n"); 193 | else 194 | return ""; 195 | } 196 | 197 | class Table2CSVSettingTab extends PluginSettingTab { 198 | plugin: Table2CSVPlugin; 199 | 200 | constructor(app: App, plugin: Table2CSVPlugin) { 201 | super(app, plugin); 202 | this.plugin = plugin; 203 | } 204 | 205 | display(): void { 206 | const {containerEl} = this; 207 | 208 | containerEl.empty(); 209 | 210 | containerEl.createEl('h2', {text: 'Settings for the Table to CSV Plugin.'}); 211 | containerEl.createEl('p', {text: 'NOTE: Currently, the exported CSV files are saved inside your vault main folder.'}); 212 | 213 | // Being able to set a path for the exports will be a future addition 214 | // ------------------------------------------------------------------ 215 | // new Setting(containerEl) 216 | // .setName('CSV file export path') 217 | // .setDesc('Enter the path where the exported CSV file should be saved. If no path is set the CSV file will be saved into your vault folder.') 218 | // .addText(text => text 219 | // .setPlaceholder('') 220 | // .setValue(this.plugin.settings.exportPath) 221 | // .onChange(async (value) => { 222 | // console.log('path: ' + value); 223 | // this.plugin.settings.exportPath = value; 224 | // await this.plugin.saveSettings(); 225 | // })); 226 | 227 | new Setting(containerEl) 228 | .setName('CSV file base filename') 229 | .setDesc('Enter the base filename. The "File Number addendum" gets added after that and finally .csv') 230 | .addText(text => text 231 | .setPlaceholder(' { 234 | //console.log('base filename: ' + value); 235 | this.plugin.settings.baseFilename = value; 236 | await this.plugin.saveSettings(); 237 | })); 238 | 239 | new Setting(containerEl) 240 | .setName('File Number addendum') 241 | .setDesc('This number gets added to the base filename and incremented after each export. Normally, you shouldn\'t need to edit this.') 242 | .addText(text => text 243 | .setPlaceholder('') 244 | .setValue(this.plugin.settings.fileNumber) 245 | .onChange(async (value) => { 246 | //console.log('fileNumber: ' + value); 247 | this.plugin.settings.fileNumber = value; 248 | await this.plugin.saveSettings(); 249 | })); 250 | 251 | new Setting(containerEl) 252 | .setName('Data fields separation character/string') 253 | .setDesc('This character will be put between each cell\'s data. Defaults to a semicolon.') 254 | .addDropdown(dropdown => dropdown 255 | .addOption('sepChar-semicolon', '; (semicolon)') 256 | .addOption('sepChar-comma', ', (comma)') 257 | .addOption('sepChar-tab', '\\t (tab)') 258 | .addOption('sepChar-pipe', '| (pipe)') 259 | .addOption('sepChar-tilde', '~ (tilde)') 260 | .addOption('sepChar-caret', '^ (caret)') 261 | .addOption('sepChar-colon', ': (colon)') 262 | .setValue(this.plugin.settings.sepChar) 263 | .onChange(async (value) => { 264 | //console.log('sepChar: ' + value); 265 | this.plugin.settings.sepChar = value; 266 | await this.plugin.saveSettings(); 267 | })); 268 | 269 | new Setting(containerEl) 270 | .setName('Quote data') 271 | .setDesc('Do you want quotation marks around each cell\'s data?') 272 | .addDropdown( dropdown => dropdown 273 | .addOption('quoteChar-noQuote', 'Don\'t quote data') 274 | .addOption('quoteChar-doubleQuotes', 'Quote data with double quote character (")') 275 | .addOption('quoteChar-singleQuotes', 'Quote data with single quote character (\')') 276 | .setValue(this.plugin.settings.quoteDataChar) 277 | .onChange(async (value) => { 278 | //console.log('quote data toggle: ' + value); 279 | this.plugin.settings.quoteDataChar = value; 280 | await this.plugin.saveSettings(); 281 | })); 282 | 283 | new Setting(containerEl) 284 | .setName('Handling of CR/LF in data') 285 | .setDesc('Choose how to handle the occurance of return and linefeed characters in data cells.') 286 | .addDropdown( dropdown => dropdown 287 | .addOption('removeCRLF-clear', 'Remove all CR & LF characters') 288 | .addOption('removeCRLF-space', 'Replace all CR & LF characters with one space') 289 | .addOption('removeCRLF-string1', 'Replace all CR & LF characters with string [CR]') 290 | .setValue(this.plugin.settings.removeCRLF) 291 | .onChange(async (value) => { 292 | this.plugin.settings.removeCRLF = value; 293 | await this.plugin.saveSettings(); 294 | })) 295 | 296 | new Setting(containerEl) 297 | .setName('Copy to clipboard, too') 298 | .setDesc('Do you want to copy the contents of the CSV file to the system clipboard, too?') 299 | .addToggle( toggle => toggle 300 | .setValue(this.plugin.settings.saveToClipboardToo) 301 | .onChange(async (value) => { 302 | //console.log('save to clipboard, too: ' + value); 303 | this.plugin.settings.saveToClipboardToo = value; 304 | await this.plugin.saveSettings(); 305 | })); 306 | 307 | } 308 | } 309 | --------------------------------------------------------------------------------