Initial commit

This commit is contained in:
Docker7530
2026-03-01 01:43:46 +08:00
commit c6125c117b
3840 changed files with 415340 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
{
"readableLineLength": false,
"strictLineBreaks": true,
"showLineNumber": true,
"promptDelete": true,
"alwaysUpdateLinks": true,
"newLinkFormat": "relative",
"useMarkdownLinks": true,
"showUnsupportedFiles": true,
"newFileLocation": "folder",
"newFileFolderPath": "000-inbox",
"attachmentFolderPath": "attachment",
"pdfExportSettings": {
"pageSize": "A4",
"landscape": false,
"margin": "0",
"downscalePercent": 100
},
"showInlineTitle": true,
"autoPairMarkdown": true,
"useTab": false,
"showIndentGuide": false,
"spellcheck": false,
"foldIndent": false
}
+8
View File
@@ -0,0 +1,8 @@
{
"enabledCssSnippets": [
"myTheme"
],
"monospaceFontFamily": "JetBrainsMono Nerd Font Mono",
"textFontFamily": "微软雅黑",
"interfaceFontFamily": "JetBrainsMono Nerd Font Mono"
}
+3
View File
@@ -0,0 +1,3 @@
{
"backlinkInDocument": false
}
+15
View File
@@ -0,0 +1,15 @@
{
"items": [
{
"type": "file",
"ctime": 1736742940138,
"path": "work/移动杭研/业务梳理/接口收纳.md"
},
{
"type": "file",
"ctime": 1768964533760,
"path": "work/移动杭研/开发记录/7.18.0/开发笔记.md",
"title": "7.18.0 开发笔记"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"snapToObjects": true,
"snapToGrid": true,
"newFileLocation": "folder",
"newFileFolderPath": "00-Inbox"
}
+8
View File
@@ -0,0 +1,8 @@
{
"pinned": [
"file-explorer:reveal-active-file",
"file-explorer:move-file",
"open-with-default-app:show",
"app:reload"
]
}
+12
View File
@@ -0,0 +1,12 @@
[
"obsidian-paste-image-rename",
"update-relative-links",
"obsidian-linter",
"templater-obsidian",
"quickadd",
"calendar",
"recent-files-obsidian",
"oz-clear-unused-images",
"obsidian-excalidraw-plugin",
"copy-url-in-preview"
]
+30
View File
@@ -0,0 +1,30 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": false,
"outgoing-link": true,
"tag-pane": true,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": true,
"file-recovery": true,
"publish": false,
"sync": true
}
+33
View File
@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": false,
"outgoing-link": true,
"tag-pane": true,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": false,
"note-composer": false,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": true,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false,
"webviewer": false,
"footnotes": true,
"bases": true
}
+5
View File
@@ -0,0 +1,5 @@
{
"folder": "calendar/diary",
"template": "attachment/templates/日记模板",
"autorun": false
}
+22
View File
@@ -0,0 +1,22 @@
{
"collapse-filter": false,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": false,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": false,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 0.09848280266864458,
"close": true
}
+51
View File
@@ -0,0 +1,51 @@
{
"workspace:goto-tab-1": [],
"workspace:goto-tab-2": [],
"workspace:goto-tab-3": [],
"workspace:goto-tab-4": [],
"workspace:goto-tab-5": [],
"workspace:goto-tab-6": [],
"workspace:goto-tab-7": [],
"workspace:goto-tab-8": [],
"editor:set-heading-1": [
{
"modifiers": [
"Mod"
],
"key": "1"
}
],
"editor:set-heading-2": [
{
"modifiers": [
"Mod"
],
"key": "2"
}
],
"editor:set-heading-3": [
{
"modifiers": [
"Mod"
],
"key": "3"
}
],
"workspace:goto-last-tab": [],
"app:open-help": [],
"app:open-settings": [],
"obsidian-memos:show-thino-editor": [
{
"modifiers": [],
"key": "F1"
}
],
"editor:toggle-comments": [],
"quickadd:runQuickAdd": [
{
"modifiers": [],
"key": "F1"
}
],
"workspace:close-window": []
}
+1
View File
@@ -0,0 +1 @@
{}
+10
View File
@@ -0,0 +1,10 @@
{
"shouldConfirmBeforeCreate": false,
"weekStart": "locale",
"wordsPerDot": 9999,
"showWeeklyNote": true,
"weeklyNoteFormat": "",
"weeklyNoteTemplate": "",
"weeklyNoteFolder": "calendar/weeks",
"localeOverride": "system-default"
}
+4459
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
{
"id": "calendar",
"name": "Calendar",
"description": "Calendar view of your daily notes",
"version": "1.5.10",
"author": "Liam Cain",
"authorUrl": "https://github.com/liamcain/",
"isDesktopOnly": false,
"minAppVersion": "0.9.11"
}
+6
View File
@@ -0,0 +1,6 @@
{
"middleClickNewTab": false,
"revealInNavigation": true,
"enableDefaultOnCanvas": false,
"pdfMenu": false
}
+9
View File
@@ -0,0 +1,9 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
"use strict";var v=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var O=(n,i,t)=>i in n?v(n,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[i]=t;var _=(n,i)=>{for(var t in i)v(n,t,{get:i[t],enumerable:!0})},R=(n,i,t,e)=>{if(i&&typeof i=="object"||typeof i=="function")for(let o of A(i))!L.call(n,o)&&o!==t&&v(n,o,{get:()=>i[o],enumerable:!(e=B(i,o))||e.enumerable});return n};var W=n=>R(v({},"__esModule",{value:!0}),n);var g=(n,i,t)=>O(n,typeof i!="symbol"?i+"":i,t);var $={};_($,{default:()=>y});module.exports=W($);var c=require("obsidian");var m=require("obsidian"),f={loadImageBlob:5e3,notice:1800};function w(n){let i=["avif","bmp","gif","jpg","jpeg","png","svg","webp","heic"];return n=n.toLowerCase(),i.some(t=>n.endsWith(`.${t}`))}function T(n){return n=new URL(n),n.search="",n.toString()}async function h(n){let i=()=>{new m.Notice(i18next.t("interface.copied_generic"),f.notice)},t=()=>{new m.Notice(i18next.t("Failed to copy image to clipboard"),f.notice)};if(n instanceof m.TFile){let a=new Blob([await n.vault.readBinary(n)],{type:`image/${n.extension}`});if(await d(a)){i();return}else{t();return}}let e=await k(n);if(e&&await d(e)){i();return}let o=`https://api.allorigins.win/raw?url=${encodeURIComponent(n)}`;if(e=await k(o),e&&await d(e)){i();return}if(e=await U(f.loadImageBlob,S(n)),e&&await d(e)){i();return}if(e=await U(f.loadImageBlob,S(o)),e&&await d(e)){i();return}t()}async function d(n){try{if(n.type!=="image/svg+xml")return await navigator.clipboard.write([new ClipboardItem({[n.type]:n})]),!0}catch(i){console.warn("Failed copying image with original mimetype, using PNG fallback - ",i)}try{return n=new Blob([n],{type:"image/png"}),await navigator.clipboard.write([new ClipboardItem({[n.type]:n})]),!0}catch(i){console.warn("Failed copying image with PNG mimetype - ",i)}return!1}async function k(n){try{return await(await fetch(n,{signal:AbortSignal.timeout(f.loadImageBlob)})).blob()}catch(i){console.warn("Failed to fetch image - ",i)}return null}function S(n){return new Promise(i=>{let t=new Image;t.crossOrigin="anonymous",t.onload=()=>{let e=document.createElement("canvas");e.width=t.width,e.height=t.height,e.getContext("2d").drawImage(t,0,0),e.toBlob(o=>{i(o)})},t.onerror=()=>{i(null)},t.src=n})}function U(n,i){let t=new Promise(e=>setTimeout(()=>{e(null)},n));return Promise.race([i,t])}function C(n,i,t,e,o){return n.on(i,t,e,o),()=>{n.off(i,t,e,o)}}function x(n,i){let t=(0,m.normalizePath)(n.vault.adapter.basePath);t=t.replace("file://","");let e=i.pathname;e=e.replace("/_capacitor_file_",""),e=e.split("/").filter(a=>a!=="").join("/");let o=decodeURI(e);if(o.startsWith(t)){let a=o.slice(t.length+1);return n.vault.getFileByPath(a)}return null}function b(n,i){n.workspace.getLeaf(!0).openFile(i,{active:!0})}var F=require("obsidian"),M=["file","open","info","system"],P={"copy-to-clipboard":{section:"info",icon:"image-file",title:"interface.label-copy"},"open-in-new-tab":{section:"open",icon:"file-plus",title:"interface.menu.open-in-new-tab"},"open-in-default-app":{section:"system",icon:"arrow-up-right",title:"plugins.open-with-default-app.action-open-file"},"show-in-explorer":{section:"system",icon:"arrow-up-right",title:`plugins.open-with-default-app.action-show-in-folder${F.Platform.isMacOS?"-mac":""}`},"reveal-in-navigation":{section:"system",icon:"folder",title:"plugins.file-explorer.action-reveal-file"},"reveal-in-navigation-tree":{section:"system",icon:"folder",title:"Reveal in File Tree Alternative"},"rename-file":{section:"info",icon:"pencil",title:"interface.menu.rename"}};function p(n,i){return n.setSection(P[i].section).setIcon(P[i].icon).setTitle(i18next.t(P[i].title))}var u=require("obsidian");var D={middleClickNewTab:!0,revealInNavigation:!0,enableDefaultOnCanvas:!1},I=class extends u.PluginSettingTab{constructor(t,e){super(t,e);g(this,"plugin");this.plugin=e}display(){let{containerEl:t}=this;t.empty(),t.createEl("h3",{text:"Image Context Menus settings"}),new u.Setting(t).setName("Middle mouse click on image link to open in new tab").addToggle(e=>{e.setValue(this.plugin.settings.middleClickNewTab).onChange(o=>{this.plugin.settings.middleClickNewTab=o,this.plugin.saveSettings()})}),new u.Setting(t).setName("Reveal file in navigation menu item").setDesc("You might want to disable this if you use a plugin for replacing default Obsidian file navigation. This plugin supports File Tree Alternative by displaying a reveal menu item for it if installed.").addToggle(e=>{e.setValue(this.plugin.settings.revealInNavigation).onChange(o=>{this.plugin.settings.revealInNavigation=o,this.plugin.saveSettings()})}),new u.Setting(t).setName("Enable regular context menu on canvas").setDesc(`The regular context menu sometimes duplicates the context menu on the canvas, so it's disabled there by default.
There is a separate context menu for images directly on the canvas, but if that's not enough (for example for images in notes on canvas), you can enable the regular context menu here too.`).addToggle(e=>{e.setValue(this.plugin.settings.enableDefaultOnCanvas).onChange(o=>{this.plugin.settings.enableDefaultOnCanvas=o,this.plugin.saveSettings()})})}};var y=class extends c.Plugin{constructor(){super(...arguments);g(this,"canvasCardMenu");g(this,"settings")}async loadSettings(){this.settings=Object.assign({},D,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}async onload(){await this.loadSettings(),this.addSettingTab(new I(this.app,this)),this.registerDocument(document),this.app.workspace.on("window-open",(t,e)=>{this.registerDocument(e.document)}),this.registerEvent(this.app.workspace.on("file-menu",(t,e,o)=>{o==="canvas-menu"&&e instanceof c.TFile&&w(`.${e.extension}`)&&(t.addItem(a=>p(a,"open-in-new-tab").onClick(()=>{b(this.app,e)})),t.addItem(a=>p(a,"copy-to-clipboard").onClick(()=>{h(e)})))})),this.registerEvent(this.app.workspace.on("canvas:node-menu",(t,e)=>{let o=e.unknownData;if(o.type==="link"){let a=T(o.url);if(!w(a))return;t.addItem(r=>p(r,"copy-to-clipboard").setSection("canvas").onClick(()=>{h(a)}))}})),this.registerEvent(this.app.workspace.on("url-menu",(t,e)=>{e=T(e),w(e)&&t.addItem(o=>p(o,"copy-to-clipboard").onClick(()=>{h(e)}))}))}registerDocument(t){let e=[C(t,"contextmenu","img",this.onImageContextMenu.bind(this),{capture:!0}),C(t,"mouseup","img",this.onImageMouseUp.bind(this))];this.register(()=>{for(let o of e)o()})}onImageContextMenu(t){var E;if(!this.settings.enableDefaultOnCanvas&&((E=this.app.workspace.getActiveFile())==null?void 0:E.extension)==="canvas")return;t.preventDefault();let e=t.target,o=new URL(e.src);if(!["app:","data:","http:","https:"].includes(o.protocol)){new c.Notice(`No handler for ${o.protocol} protocol`);return}let r=new c.Menu,l=x(this.app,o);r.addSections(Array.from(M)),l&&r.addItem(s=>p(s,"rename-file").onClick(()=>this.app.fileManager.promptForFileRename(l))),r.addItem(s=>p(s,"copy-to-clipboard").onClick(()=>{h(l!=null?l:e.src)})),l&&(c.Platform.isMobile&&r.addItem(s=>s.setTitle(l.name).setSection("file").setIsLabel(!0)),r.addItem(s=>p(s,"open-in-new-tab").onClick(()=>{b(this.app,l)})),c.Platform.isDesktop&&(r.addItem(s=>p(s,"open-in-default-app").onClick(()=>{this.app.openWithDefaultApp(l.path)})),r.addItem(s=>p(s,"show-in-explorer").onClick(()=>{this.app.showInFolder(l.path)}))),this.settings.revealInNavigation&&r.addItem(s=>p(s,"reveal-in-navigation").onClick(()=>{var N;(N=this.app.internalPlugins.getEnabledPluginById("file-explorer"))==null||N.revealInFolder(l)})),this.app.plugins.enabledPlugins.has("file-tree-alternative")&&r.addItem(s=>p(s,"reveal-in-navigation-tree").onClick(()=>{self.dispatchEvent(new CustomEvent("fta-reveal-file",{detail:{file:l}}))}))),r.showAtPosition({x:t.pageX,y:t.pageY})}onImageMouseUp(t){let e=t.target;if(t.button===1&&this.settings.middleClickNewTab){let a=x(this.app,new URL(e.src));if(!a)return;b(this.app,a)}}};
/* nosourcemap */
+11
View File
@@ -0,0 +1,11 @@
{
"id": "copy-url-in-preview",
"name": "Image Context Menus",
"version": "1.11.2",
"minAppVersion": "1.6.6",
"description": "Copy to clipboard, Open in default app, Show in system explorer, Reveal file in navigation, Open in new tab, Rename context menus for images.",
"author": "NomarCub",
"authorUrl": "https://github.com/NomarCub",
"fundingUrl": "https://ko-fi.com/nomarcub",
"isDesktopOnly": false
}
+817
View File
@@ -0,0 +1,817 @@
{
"copyLinkToElemenetAnchorTo100": false,
"copyFrameLinkByName": false,
"disableDoubleClickTextEditing": false,
"folder": "excalidraw",
"cropFolder": "excalidraw/cropped",
"annotateFolder": "excalidraw/annotations",
"embedUseExcalidrawFolder": true,
"templateFilePath": "excalidraw/Template.excalidraw",
"scriptFolderPath": "excalidraw/scripts",
"fontAssetsPath": "excalidraw/fonts",
"loadChineseFonts": false,
"loadJapaneseFonts": false,
"loadKoreanFonts": false,
"compress": true,
"decompressForMDView": false,
"onceOffCompressFlagReset": true,
"onceOffGPTVersionReset": true,
"autosave": true,
"autosaveIntervalDesktop": 60000,
"autosaveIntervalMobile": 30000,
"drawingFilenamePrefix": "Drawing ",
"drawingEmbedPrefixWithFilename": true,
"drawingFilnameEmbedPostfix": " ",
"drawingFilenameDateTime": "YYYY-MM-DD HH.mm.ss",
"useExcalidrawExtension": true,
"cropSuffix": "",
"cropPrefix": "cropped_",
"annotateSuffix": "",
"annotatePrefix": "annotated_",
"annotatePreserveSize": false,
"previewImageType": "SVGIMG",
"renderingConcurrency": 3,
"allowImageCache": true,
"allowImageCacheInScene": true,
"displayExportedImageIfAvailable": false,
"previewMatchObsidianTheme": false,
"width": "400",
"height": "",
"overrideObsidianFontSize": false,
"dynamicStyling": "colorful",
"isLeftHanded": false,
"desktopUIMode": "tray",
"tabletUIMode": "compact",
"iframeMatchExcalidrawTheme": true,
"matchTheme": false,
"matchThemeAlways": false,
"matchThemeTrigger": false,
"defaultMode": "normal",
"defaultPenMode": "never",
"penModeDoubleTapEraser": true,
"penModeSingleFingerPanning": true,
"penModeCrosshairVisible": true,
"panWithRightMouseButton": false,
"renderImageInMarkdownReadingMode": false,
"renderImageInHoverPreviewForMDNotes": false,
"renderImageInMarkdownToPDF": false,
"allowPinchZoom": false,
"allowWheelZoom": true,
"zoomToFitOnOpen": true,
"zoomToFitOnResize": true,
"zoomToFitMaxLevel": 2,
"zoomStep": 0.05,
"zoomMin": 0.1,
"zoomMax": 30,
"linkPrefix": "📍",
"urlPrefix": "🌐",
"parseTODO": false,
"todo": "☐",
"done": "🗹",
"hoverPreviewWithoutCTRL": false,
"linkOpacity": 1,
"openInAdjacentPane": true,
"showSecondOrderLinks": true,
"focusOnFileTab": true,
"openInMainWorkspace": true,
"showLinkBrackets": true,
"syncElementLinkWithText": false,
"allowCtrlClick": true,
"forceWrap": false,
"pageTransclusionCharLimit": 200,
"wordWrappingDefault": 0,
"removeTransclusionQuoteSigns": true,
"iframelyAllowed": true,
"pngExportScale": 1,
"exportWithTheme": true,
"exportWithBackground": true,
"exportPaddingSVG": 10,
"exportEmbedScene": false,
"keepInSync": false,
"autoexportSVG": false,
"autoexportPNG": false,
"autoExportLightAndDark": false,
"autoexportExcalidraw": false,
"embedType": "excalidraw",
"embedMarkdownCommentLinks": true,
"embedWikiLink": true,
"syncExcalidraw": false,
"experimentalFileType": false,
"experimentalFileTag": "✏️",
"experimentalLivePreview": true,
"fadeOutExcalidrawMarkup": false,
"loadPropertySuggestions": true,
"experimentalEnableFourthFont": false,
"experimantalFourthFont": "Virgil",
"addDummyTextElement": false,
"zoteroCompatibility": false,
"fieldSuggester": true,
"compatibilityMode": false,
"drawingOpenCount": 0,
"library": "deprecated",
"library2": {
"type": "excalidrawlib",
"version": 2,
"source": "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/2.19.1",
"libraryItems": []
},
"imageElementNotice": true,
"mdSVGwidth": 500,
"mdSVGmaxHeight": 800,
"mdFont": "Virgil",
"mdFontColor": "Black",
"mdBorderColor": "Black",
"mdCSS": "",
"scriptEngineSettings": {},
"previousRelease": "2.20.4",
"showReleaseNotes": true,
"compareManifestToPluginVersion": true,
"showNewVersionNotification": true,
"latexBoilerplate": "\\color{blue}",
"latexPreambleLocation": "preamble.sty",
"taskboneEnabled": false,
"taskboneAPIkey": "",
"pinnedScripts": [],
"sidepanelTabs": [],
"customPens": [
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "highlighter",
"freedrawOnly": true,
"strokeColor": "#FFC47C",
"backgroundColor": "#FFC47C",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": true,
"outlineWidth": 4,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 0,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "finetip",
"freedrawOnly": false,
"strokeColor": "#3E6F8D",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0.5,
"roughness": 0,
"penOptions": {
"highlighter": false,
"hasOutline": false,
"outlineWidth": 1,
"constantPressure": true,
"options": {
"smoothing": 0.4,
"thinning": -0.5,
"streamline": 0.4,
"easing": "linear",
"start": {
"taper": 5,
"cap": false,
"easing": "linear"
},
"end": {
"taper": 5,
"cap": false,
"easing": "linear"
}
}
}
},
{
"type": "fountain",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"smoothing": 0.2,
"thinning": 0.6,
"streamline": 0.2,
"easing": "easeInOutSine",
"start": {
"taper": 150,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 1,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "marker",
"freedrawOnly": true,
"strokeColor": "#B83E3E",
"backgroundColor": "#FF7C7C",
"fillStyle": "dashed",
"strokeWidth": 2,
"roughness": 3,
"penOptions": {
"highlighter": false,
"constantPressure": true,
"hasOutline": true,
"outlineWidth": 4,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 0,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "thick-thin",
"freedrawOnly": true,
"strokeColor": "#CECDCC",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"cap": true,
"taper": true,
"easing": "linear"
}
}
}
},
{
"type": "thin-thick-thin",
"freedrawOnly": true,
"strokeColor": "#CECDCC",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"cap": true,
"taper": true,
"easing": "linear"
},
"end": {
"cap": true,
"taper": true,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
}
],
"numberOfCustomPens": 0,
"pdfScale": 4,
"pdfBorderBox": true,
"pdfFrame": false,
"pdfGapSize": 20,
"pdfGroupPages": false,
"pdfLockAfterImport": true,
"pdfNumColumns": 1,
"pdfNumRows": 1,
"pdfDirection": "right",
"pdfImportScale": 0.3,
"gridSettings": {
"DYNAMIC_COLOR": true,
"COLOR": "#000000",
"OPACITY": 50
},
"laserSettings": {
"DECAY_LENGTH": 50,
"DECAY_TIME": 1000,
"COLOR": "#ff0000"
},
"embeddableMarkdownDefaults": {
"useObsidianDefaults": false,
"backgroundMatchCanvas": false,
"backgroundMatchElement": true,
"backgroundColor": "#fff",
"backgroundOpacity": 60,
"borderMatchElement": true,
"borderColor": "#fff",
"borderOpacity": 0,
"filenameVisible": false
},
"markdownNodeOneClickEditing": false,
"canvasImmersiveEmbed": true,
"startupScriptPath": "",
"aiEnabled": true,
"openAIAPIToken": "",
"openAIDefaultTextModel": "gpt-3.5-turbo-1106",
"openAIDefaultTextModelMaxTokens": 4096,
"openAIDefaultVisionModel": "gpt-4o",
"openAIDefaultImageGenerationModel": "dall-e-3",
"openAIURL": "https://api.openai.com/v1/chat/completions",
"openAIImageGenerationURL": "https://api.openai.com/v1/images/generations",
"openAIImageEditsURL": "https://api.openai.com/v1/images/edits",
"openAIImageVariationURL": "https://api.openai.com/v1/images/variations",
"modifierKeyConfig": {
"Mac": {
"LocalFileDragAction": {
"defaultAction": "image-import",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "embeddable"
}
]
},
"WebBrowserDragAction": {
"defaultAction": "image-url",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "link"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
}
]
},
"InternalDragAction": {
"defaultAction": "link",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": true,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": true,
"result": "image-fullsize"
}
]
},
"LinkClickAction": {
"defaultAction": "new-tab",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "active-pane"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "new-tab"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "new-pane"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "popout-window"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": true,
"result": "md-properties"
}
]
}
},
"Win": {
"LocalFileDragAction": {
"defaultAction": "image-import",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
}
]
},
"WebBrowserDragAction": {
"defaultAction": "image-url",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
}
]
},
"InternalDragAction": {
"defaultAction": "link",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "image-fullsize"
}
]
},
"LinkClickAction": {
"defaultAction": "new-tab",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "active-pane"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "new-tab"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "new-pane"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "popout-window"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": true,
"result": "md-properties"
}
]
}
}
},
"slidingPanesSupport": false,
"areaZoomLimit": 1,
"longPressDesktop": 500,
"longPressMobile": 500,
"doubleClickLinkOpenViewMode": true,
"isDebugMode": false,
"rank": "Bronze",
"modifierKeyOverrides": [
{
"modifiers": [
"Mod"
],
"key": "Enter"
},
{
"modifiers": [
"Mod"
],
"key": "k"
},
{
"modifiers": [
"Mod"
],
"key": "G"
}
],
"showSplashscreen": true,
"pdfSettings": {
"pageSize": "A4",
"pageOrientation": "portrait",
"fitToPage": 1,
"paperColor": "white",
"customPaperColor": "#ffffff",
"alignment": "center",
"margin": "normal"
},
"disableContextMenu": false,
"defaultTrayMode": true,
"compactModeOnTablets": true
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
"version": "2.20.4",
"minAppVersion": "1.5.7",
"description": "Sketch Your Mind. An Obsidian plugin to edit and view Excalidraw drawings. Enter the world of 4D Visual PKM.",
"author": "Zsolt Viczian",
"authorUrl": "https://excalidraw-obsidian.online",
"fundingUrl": "https://ko-fi.com/zsolt",
"helpUrl": "https://github.com/zsviczian/obsidian-excalidraw-plugin#readme",
"isDesktopOnly": false
}
File diff suppressed because one or more lines are too long
+297
View File
@@ -0,0 +1,297 @@
{
"ruleConfigs": {
"add-blank-line-after-yaml": {
"enabled": true
},
"dedupe-yaml-array-values": {
"enabled": true,
"dedupe-alias-key": true,
"dedupe-tag-key": true,
"dedupe-array-keys": true,
"ignore-keys": ""
},
"escape-yaml-special-characters": {
"enabled": true,
"try-to-escape-single-line-arrays": false
},
"force-yaml-escape": {
"enabled": false,
"force-yaml-escape-keys": ""
},
"format-tags-in-yaml": {
"enabled": true
},
"format-yaml-array": {
"enabled": true,
"alias-key": true,
"tag-key": true,
"default-array-style": "multi-line",
"default-array-keys": true,
"force-single-line-array-style": "",
"force-multi-line-array-style": ""
},
"insert-yaml-attributes": {
"enabled": false,
"text-to-insert": "aliases: \ntags: "
},
"move-tags-to-yaml": {
"enabled": false,
"how-to-handle-existing-tags": "Remove whole tag",
"tags-to-ignore": ""
},
"remove-yaml-keys": {
"enabled": false,
"yaml-keys-to-remove": ""
},
"sort-yaml-array-values": {
"enabled": false,
"sort-alias-key": false,
"sort-tag-key": false,
"sort-array-keys": false,
"ignore-keys": "",
"sort-order": "Ascending Alphabetical"
},
"yaml-key-sort": {
"enabled": false,
"yaml-key-priority-sort-order": "",
"priority-keys-at-start-of-yaml": true,
"yaml-sort-order-for-other-keys": "None"
},
"yaml-timestamp": {
"enabled": false,
"date-created": true,
"date-created-key": "date created",
"date-modified": true,
"date-modified-key": "date modified",
"format": "dddd, MMMM Do YYYY, h:mm:ss a",
"date-created-source-of-truth": "file system",
"date-modified-source-of-truth": "file system",
"convert-to-utc": false,
"update-on-file-contents-updated": "never"
},
"yaml-title": {
"enabled": false,
"title-key": "title",
"mode": "first-h1-or-filename-if-h1-missing"
},
"yaml-title-alias": {
"enabled": false,
"preserve-existing-alias-section-style": true,
"keep-alias-that-matches-the-filename": false,
"use-yaml-key-to-keep-track-of-old-filename-or-heading": true,
"alias-helper-key": "linter-yaml-title-alias"
},
"capitalize-headings": {
"enabled": false,
"style": "Title Case",
"ignore-case-words": true,
"ignore-words": "macOS, iOS, iPhone, iPad, JavaScript, TypeScript, AppleScript, I",
"lowercase-words": "a, an, the, aboard, about, abt., above, abreast, absent, across, after, against, along, aloft, alongside, amid, amidst, mid, midst, among, amongst, anti, apropos, around, round, as, aslant, astride, at, atop, ontop, bar, barring, before, B4, behind, below, beneath, neath, beside, besides, between, 'tween, beyond, but, by, chez, circa, c., ca., come, concerning, contra, counting, cum, despite, spite, down, during, effective, ere, except, excepting, excluding, failing, following, for, from, in, including, inside, into, less, like, minus, modulo, mod, near, nearer, nearest, next, notwithstanding, of, o', off, offshore, on, onto, opposite, out, outside, over, o'er, pace, past, pending, per, plus, post, pre, pro, qua, re, regarding, respecting, sans, save, saving, short, since, sub, than, through, thru, throughout, thruout, till, times, to, t', touching, toward, towards, under, underneath, unlike, until, unto, up, upon, versus, vs., v., via, vice, vis-à-vis, wanting, with, w/, w., c̄, within, w/i, without, 'thout, w/o, abroad, adrift, aft, afterward, afterwards, ahead, apart, ashore, aside, away, back, backward, backwards, beforehand, downhill, downstage, downstairs, downstream, downward, downwards, downwind, east, eastward, eastwards, forth, forward, forwards, heavenward, heavenwards, hence, henceforth, here, hereby, herein, hereof, hereto, herewith, home, homeward, homewards, indoors, inward, inwards, leftward, leftwards, north, northeast, northward, northwards, northwest, now, onward, onwards, outdoors, outward, outwards, overboard, overhead, overland, overseas, rightward, rightwards, seaward, seawards, skywards, skyward, south, southeast, southwards, southward, southwest, then, thence, thenceforth, there, thereby, therein, thereof, thereto, therewith, together, underfoot, underground, uphill, upstage, upstairs, upstream, upward, upwards, upwind, west, westward, westwards, when, whence, where, whereby, wherein, whereto, wherewith, although, because, considering, given, granted, if, lest, once, provided, providing, seeing, so, supposing, though, unless, whenever, whereas, wherever, while, whilst, ago, according to, as regards, counter to, instead of, owing to, pertaining to, at the behest of, at the expense of, at the hands of, at risk of, at the risk of, at variance with, by dint of, by means of, by virtue of, by way of, for the sake of, for sake of, for lack of, for want of, from want of, in accordance with, in addition to, in case of, in charge of, in compliance with, in conformity with, in contact with, in exchange for, in favor of, in front of, in lieu of, in light of, in the light of, in line with, in place of, in point of, in quest of, in relation to, in regard to, with regard to, in respect to, with respect to, in return for, in search of, in step with, in touch with, in terms of, in the name of, in view of, on account of, on behalf of, on grounds of, on the grounds of, on the part of, on top of, with a view to, with the exception of, à la, a la, as soon as, as well as, close to, due to, far from, in case, other than, prior to, pursuant to, regardless of, subsequent to, as long as, as much as, as far as, by the time, in as much as, inasmuch, in order to, in order that, even, provide that, if only, whether, whose, whoever, why, how, or not, whatever, what, both, and, or, not only, but also, either, neither, nor, just, rather, no sooner, such, that, yet, is, it"
},
"file-name-heading": {
"enabled": false
},
"header-increment": {
"enabled": false,
"start-at-h2": false
},
"headings-start-line": {
"enabled": false
},
"remove-trailing-punctuation-in-heading": {
"enabled": false,
"punctuation-to-remove": ".,;:!。,;:!"
},
"footnote-after-punctuation": {
"enabled": false
},
"move-footnotes-to-the-bottom": {
"enabled": false,
"include-blank-line-between-footnotes": false
},
"re-index-footnotes": {
"enabled": false
},
"auto-correct-common-misspellings": {
"enabled": false,
"ignore-words": "",
"skip-words-with-multiple-capitals": false,
"extra-auto-correct-files": []
},
"blockquote-style": {
"enabled": true,
"style": "space"
},
"convert-bullet-list-markers": {
"enabled": true
},
"default-language-for-code-fences": {
"enabled": false,
"default-language": ""
},
"emphasis-style": {
"enabled": true,
"style": "asterisk"
},
"no-bare-urls": {
"enabled": false,
"no-bare-uris": false
},
"ordered-list-style": {
"enabled": true,
"number-style": "ascending",
"list-end-style": "."
},
"proper-ellipsis": {
"enabled": true
},
"quote-style": {
"enabled": false,
"single-quote-enabled": true,
"single-quote-style": "''",
"double-quote-enabled": true,
"double-quote-style": "\"\""
},
"remove-consecutive-list-markers": {
"enabled": false
},
"remove-empty-list-markers": {
"enabled": true
},
"remove-hyphenated-line-breaks": {
"enabled": false
},
"remove-multiple-spaces": {
"enabled": false
},
"strong-style": {
"enabled": true,
"style": "asterisk"
},
"two-spaces-between-lines-with-content": {
"enabled": false,
"line-break-indicator": " "
},
"unordered-list-style": {
"enabled": true,
"list-style": "-"
},
"compact-yaml": {
"enabled": true,
"inner-new-lines": true
},
"consecutive-blank-lines": {
"enabled": true
},
"convert-spaces-to-tabs": {
"enabled": false,
"tabsize": 4
},
"empty-line-around-blockquotes": {
"enabled": true
},
"empty-line-around-code-fences": {
"enabled": true
},
"empty-line-around-math-blocks": {
"enabled": true
},
"empty-line-around-tables": {
"enabled": true
},
"heading-blank-lines": {
"enabled": true,
"bottom": true,
"empty-line-after-yaml": true
},
"line-break-at-document-end": {
"enabled": true
},
"move-math-block-indicators-to-their-own-line": {
"enabled": true
},
"paragraph-blank-lines": {
"enabled": true
},
"remove-empty-lines-between-list-markers-and-checklists": {
"enabled": true
},
"remove-link-spacing": {
"enabled": true
},
"remove-space-around-characters": {
"enabled": false,
"include-fullwidth-forms": true,
"include-cjk-symbols-and-punctuation": true,
"include-dashes": true,
"other-symbols": ""
},
"remove-space-before-or-after-characters": {
"enabled": false,
"characters-to-remove-space-before": ",!?;:).’”]",
"characters-to-remove-space-after": "¿¡‘“(["
},
"space-after-list-markers": {
"enabled": true
},
"space-between-chinese-japanese-or-korean-and-english-or-numbers": {
"enabled": false,
"english-symbols-punctuation-before": "-+;:'\"°%$)]",
"english-symbols-punctuation-after": "-+'\"([¥$"
},
"trailing-spaces": {
"enabled": true,
"two-space-line-break": true
},
"add-blockquote-indentation-on-paste": {
"enabled": false
},
"prevent-double-checklist-indicator-on-paste": {
"enabled": false
},
"prevent-double-list-item-indicator-on-paste": {
"enabled": false
},
"proper-ellipsis-on-paste": {
"enabled": false
},
"remove-hyphens-on-paste": {
"enabled": false
},
"remove-leading-or-trailing-whitespace-on-paste": {
"enabled": false
},
"remove-leftover-footnotes-from-quote-on-paste": {
"enabled": false
},
"remove-multiple-blank-lines-on-paste": {
"enabled": false
},
"empty-line-around-horizontal-rules": {
"enabled": true
}
},
"lintOnSave": true,
"recordLintOnSaveLogs": false,
"displayChanged": true,
"suppressMessageWhenNoChange": false,
"lintOnFileChange": true,
"displayLintOnFileChangeNotice": true,
"settingsConvertedToConfigKeyValues": true,
"foldersToIgnore": [
"attachment",
"excalidraw"
],
"filesToIgnore": [],
"linterLocale": "system-default",
"logLevel": "ERROR",
"lintCommands": [],
"customRegexes": [],
"commonStyles": {
"aliasArrayStyle": "multi-line",
"tagArrayStyle": "multi-line",
"minimumNumberOfDollarSignsToBeAMathBlock": 2,
"escapeCharacter": "\"",
"removeUnnecessaryEscapeCharsForMultiLineArrays": true
}
}
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
{
"id": "obsidian-linter",
"name": "Linter",
"version": "1.31.0",
"minAppVersion": "1.9.0",
"description": "Formats and styles your notes. It can be used to format YAML tags, aliases, arrays, and metadata; footnotes; headings; spacing; math blocks; regular markdown contents like list, italics, and bold styles; and more with the use of custom rule options as well.",
"author": "Victor Tao",
"authorUrl": "https://github.com/platers",
"helpUrl": "https://platers.github.io/obsidian-linter/",
"isDesktopOnly": false
}
+1
View File
@@ -0,0 +1 @@
.linter-navigation-item{align-items:center;background-color:var(--background-primary-secondary-alt);border:1px solid var(--background-modifier-border);border-radius:100px;border-radius:8px 8px 2px 2px;cursor:pointer;display:flex;flex-direction:row;font-size:16px;font-weight:700;gap:4px;height:32px;overflow:hidden;padding:4px 6px;transition:color .25s ease-in-out,padding .25s ease-in-out,background-color .35s cubic-bezier(.45,.25,.83,.67),max-width .35s cubic-bezier(.57,.04,.58,1);white-space:nowrap}@media screen and (max-width:1325px){.linter-navigation-item.linter-desktop{max-width:32px}}@media screen and (max-width:800px){.linter-navigation-item.linter-mobile{max-width:32px}}.linter-navigation-item-icon,.linter-warning{padding-top:5px}.linter-navigation-item:hover{border-color:var(--interactive-accent-hover);border-bottom:0}.linter-navigation-item-selected{background-color:var(--interactive-accent)!important;border:1px solid var(--background-modifier-border);border-bottom:0;border-radius:8px 8px 2px 2px;color:var(--text-on-accent);max-width:100%!important;padding:4px 9px!important;transition:color .25s ease-in-out,padding .25s ease-in-out,background-color .35s cubic-bezier(.45,.25,.83,.67),max-width .45s cubic-bezier(.57,.04,.58,1) .2s}.linter{transition:transform .4s 0s}.linter-setting-title{align-items:baseline;display:flex;gap:30px;justify-content:space-between}.linter-setting-title.linter-mobile{justify-content:space-around}.linter-setting-title h1{font-weight:900;margin-bottom:12px;margin-top:6px}.linter-setting-header{margin-bottom:24px;overflow-x:auto;overflow-y:hidden}.linter-setting-header .linter-setting-tab-group{align-items:flex-end;display:flex;flex-wrap:wrap;width:100%}.linter-setting-tab-group{border-bottom:2px solid var(--background-modifier-border);margin-top:6px;padding-left:2px;padding-right:2px}.linter-setting-header .linter-tab-settings{border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;font-weight:600;padding:6px 12px;white-space:nowrap}.linter-setting-header .linter-tab-settings:first-child{margin-left:6px}.linter-setting-header .linter-tab-settings.linter-tab-settings-active{border:2px solid var(--background-modifier-border);border-bottom-color:var(--background-primary);border-radius:2px;transform:translateY(2px)}.linter-navigation-item:not(.linter-navigation-item-selected)>span:nth-child(2),.linter-visually-hidden{border:0;clip:rect(0 0 0 0);clip-path:rect(0 0 0 0);height:auto;margin:0;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}textarea.full-width{margin-bottom:.8em;margin-top:.8em;min-height:10em;width:100%}.full-width-textbox-input-wrapper{position:relative}.settings-copy-button{margin:0 0 0 auto;padding:4px;position:absolute;right:.8em;top:.8em}.settings-copy-button svg.linter-clipboard path{fill:var(--text-faint)}.settings-copy-button svg.linter-success path{fill:var(--interactive-success)}.settings-copy-button:active,.settings-copy-button:hover{cursor:pointer}.settings-copy-button:active svg path,.settings-copy-button:hover svg path{fill:var(--text-accent-hover);transition:all .3s ease}.settings-copy-button:focus{outline:0}.linter-custom-regex-replacement-container div:last-child{border:none}.linter-custom-regex-replacement{border:none;border-bottom:var(--hr-thickness) solid;border-color:var(--hr-color);margin-bottom:15px}.linter-custom-regex-replacement-row2{flex-wrap:wrap}.linter-custom-regex-replacement-normal-input{width:40%}.linter-custom-regex-replacement-flags{width:15%}.linter-custom-regex-replacement-label{flex-direction:row-reverse}.linter-custom-regex-replacement-label-input{width:50%}.linter-files-to-ignore-container div:last-child{border:none}.linter-files-to-ignore{border:none;border-bottom:var(--hr-thickness) solid;border-color:var(--hr-color);margin-bottom:15px}.linter-files-to-ignore-normal-input{width:40%}.linter-files-to-ignore-flags{width:15%}.linter-no-border{border:none}.linter-border-bottom{border-bottom:1px solid var(--background-modifier-border);border-top:0;margin-bottom:.75em}.linter-no-padding-top{padding-top:0}.custom-row-description{margin-top:0}.modal-warn,.search-zero-state{font-weight:700}.modal-heading,.search-zero-state{text-align:center}
+10
View File
@@ -0,0 +1,10 @@
{
"imageNamePattern": "image-{{DATE:YYYYMMDDHHmmssSSS}}",
"dupNumberAtStart": false,
"dupNumberDelimiter": "-",
"dupNumberAlways": false,
"autoRename": true,
"handleAllAttachments": false,
"excludeExtensionPattern": "",
"disableRenameNotice": true
}
+942
View File
@@ -0,0 +1,942 @@
/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD */
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
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());
});
};
// package.json
var require_package = __commonJS({
"package.json"(exports, module2) {
module2.exports = {
name: "obsidian-paste-image-rename",
version: "1.6.1",
main: "main.js",
scripts: {
start: "node esbuild.config.mjs",
build: "tsc -noEmit -skipLibCheck && BUILD_ENV=production node esbuild.config.mjs && cp manifest.json build",
version: "node version-bump.mjs && git add manifest.json versions.json",
release: "npm run build && gh release create ${npm_package_version} build/*"
},
keywords: [],
author: "Reorx",
license: "MIT",
devDependencies: {
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"builtin-modules": "^3.3.0",
esbuild: "0.16.17",
obsidian: "^1.1.1",
tslib: "2.5.0",
typescript: "4.9.4"
},
dependencies: {
"cash-dom": "^8.1.2"
}
};
}
});
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => PasteImageRenamePlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian2 = require("obsidian");
// src/batch.ts
var import_obsidian = require("obsidian");
// src/utils.ts
var DEBUG = false;
if (DEBUG)
console.log("DEBUG is enabled");
function debugLog(...args) {
if (DEBUG) {
console.log(new Date().toISOString().slice(11, 23), ...args);
}
}
function createElementTree(rootEl, opts) {
const result = {
el: rootEl.createEl(opts.tag, opts),
children: []
};
const children = opts.children || [];
for (const child of children) {
result.children.push(createElementTree(result.el, child));
}
return result;
}
var path = {
// Credit: @creationix/path.js
join(...partSegments) {
let parts = [];
for (let i = 0, l = partSegments.length; i < l; i++) {
parts = parts.concat(partSegments[i].split("/"));
}
const newParts = [];
for (let i = 0, l = parts.length; i < l; i++) {
const part = parts[i];
if (!part || part === ".")
continue;
else
newParts.push(part);
}
if (parts[0] === "")
newParts.unshift("");
return newParts.join("/");
},
// returns the last part of a path, e.g. 'foo.jpg'
basename(fullpath) {
const sp = fullpath.split("/");
return sp[sp.length - 1];
},
// return extension without dot, e.g. 'jpg'
extension(fullpath) {
const positions = [...fullpath.matchAll(new RegExp("\\.", "gi"))].map((a) => a.index);
return fullpath.slice(positions[positions.length - 1] + 1);
}
};
var filenameNotAllowedChars = /[^\p{L}0-9~`!@$&*()\-_=+{};'",<.>? ]/ug;
var sanitizer = {
filename(s) {
return s.replace(filenameNotAllowedChars, "").trim();
},
delimiter(s) {
s = this.filename(s);
if (!s)
s = "-";
return s;
}
};
function escapeRegExp(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function lockInputMethodComposition(el) {
const state = {
lock: false
};
el.addEventListener("compositionstart", () => {
state.lock = true;
});
el.addEventListener("compositionend", () => {
state.lock = false;
});
return state;
}
// src/batch.ts
var ImageBatchRenameModal = class extends import_obsidian.Modal {
constructor(app, activeFile, renameFunc, onClose) {
super(app);
this.activeFile = activeFile;
this.renameFunc = renameFunc;
this.onCloseExtra = onClose;
this.state = {
namePattern: "",
extPattern: "",
nameReplace: "",
renameTasks: []
};
}
onOpen() {
this.containerEl.addClass("image-rename-modal");
const { contentEl, titleEl } = this;
titleEl.setText("Batch rename embeded files");
const namePatternSetting = new import_obsidian.Setting(contentEl).setName("Name pattern").setDesc("Please input the name pattern to match files (regex)").addText((text) => text.setValue(this.state.namePattern).onChange(
(value) => __async(this, null, function* () {
this.state.namePattern = value;
})
));
const npInputEl = namePatternSetting.controlEl.children[0];
npInputEl.focus();
const npInputState = lockInputMethodComposition(npInputEl);
npInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !npInputState.lock) {
e.preventDefault();
if (!this.state.namePattern) {
errorEl.innerText = 'Error: "Name pattern" could not be empty';
errorEl.style.display = "block";
return;
}
this.matchImageNames(tbodyEl);
}
}));
const extPatternSetting = new import_obsidian.Setting(contentEl).setName("Extension pattern").setDesc("Please input the extension pattern to match files (regex)").addText((text) => text.setValue(this.state.extPattern).onChange(
(value) => __async(this, null, function* () {
this.state.extPattern = value;
})
));
const extInputEl = extPatternSetting.controlEl.children[0];
extInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter") {
e.preventDefault();
this.matchImageNames(tbodyEl);
}
}));
const nameReplaceSetting = new import_obsidian.Setting(contentEl).setName("Name replace").setDesc("Please input the string to replace the matched name (use $1, $2 for regex groups)").addText((text) => text.setValue(this.state.nameReplace).onChange(
(value) => __async(this, null, function* () {
this.state.nameReplace = value;
})
));
const nrInputEl = nameReplaceSetting.controlEl.children[0];
const nrInputState = lockInputMethodComposition(nrInputEl);
nrInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !nrInputState.lock) {
e.preventDefault();
this.matchImageNames(tbodyEl);
}
}));
const matchedContainer = contentEl.createDiv({
cls: "matched-container"
});
const tableET = createElementTree(matchedContainer, {
tag: "table",
children: [
{
tag: "thead",
children: [
{
tag: "tr",
children: [
{
tag: "td",
text: "Original path"
},
{
tag: "td",
text: "Renamed Name"
}
]
}
]
},
{
tag: "tbody"
}
]
});
const tbodyEl = tableET.children[1].el;
const errorEl = contentEl.createDiv({
cls: "error",
attr: {
style: "display: none;"
}
});
new import_obsidian.Setting(contentEl).addButton((button) => {
button.setButtonText("Rename all").setClass("mod-cta").onClick(() => {
new ConfirmModal(
this.app,
"Confirm rename all",
`Are you sure? This will rename all the ${this.state.renameTasks.length} images matched the pattern.`,
() => {
this.renameAll();
this.close();
}
).open();
});
}).addButton((button) => {
button.setButtonText("Cancel").onClick(() => {
this.close();
});
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
this.onCloseExtra();
}
renameAll() {
return __async(this, null, function* () {
debugLog("renameAll", this.state);
for (const task of this.state.renameTasks) {
yield this.renameFunc(task.file, task.name);
}
});
}
matchImageNames(tbodyEl) {
const { state } = this;
const renameTasks = [];
tbodyEl.empty();
const fileCache = this.app.metadataCache.getFileCache(this.activeFile);
if (!fileCache || !fileCache.embeds)
return;
const namePatternRegex = new RegExp(state.namePattern, "g");
const extPatternRegex = new RegExp(state.extPattern);
fileCache.embeds.forEach((embed) => {
const file = this.app.metadataCache.getFirstLinkpathDest(embed.link, this.activeFile.path);
if (!file) {
console.warn("file not found", embed.link);
return;
}
if (state.extPattern) {
const m0 = extPatternRegex.exec(file.extension);
if (!m0)
return;
}
const stem = file.basename;
namePatternRegex.lastIndex = 0;
const m1 = namePatternRegex.exec(stem);
if (!m1)
return;
let renamedName = file.name;
if (state.nameReplace) {
namePatternRegex.lastIndex = 0;
renamedName = stem.replace(namePatternRegex, state.nameReplace);
renamedName = `${renamedName}.${file.extension}`;
}
renameTasks.push({
file,
name: renamedName
});
createElementTree(tbodyEl, {
tag: "tr",
children: [
{
tag: "td",
children: [
{
tag: "span",
text: file.name
},
{
tag: "div",
text: file.path,
attr: {
class: "file-path"
}
}
]
},
{
tag: "td",
children: [
{
tag: "span",
text: renamedName
},
{
tag: "div",
text: path.join(file.parent.path, renamedName),
attr: {
class: "file-path"
}
}
]
}
]
});
});
debugLog("new renameTasks", renameTasks);
state.renameTasks = renameTasks;
}
};
var ConfirmModal = class extends import_obsidian.Modal {
constructor(app, title, message, onConfirm) {
super(app);
this.title = title;
this.message = message;
this.onConfirm = onConfirm;
}
onOpen() {
const { contentEl, titleEl } = this;
titleEl.setText(this.title);
contentEl.createEl("p", {
text: this.message
});
new import_obsidian.Setting(contentEl).addButton((button) => {
button.setButtonText("Yes").setClass("mod-warning").onClick(() => {
this.onConfirm();
this.close();
});
}).addButton((button) => {
button.setButtonText("No").onClick(() => {
this.close();
});
});
}
};
// src/template.ts
var dateTmplRegex = /{{DATE:([^}]+)}}/gm;
var frontmatterTmplRegex = /{{frontmatter:([^}]+)}}/gm;
var replaceDateVar = (s, date) => {
const m = dateTmplRegex.exec(s);
if (!m)
return s;
return s.replace(m[0], date.format(m[1]));
};
var replaceFrontmatterVar = (s, frontmatter) => {
if (!frontmatter)
return s;
const m = frontmatterTmplRegex.exec(s);
if (!m)
return s;
return s.replace(m[0], frontmatter[m[1]] || "");
};
var renderTemplate = (tmpl, data, frontmatter) => {
const now = window.moment();
let text = tmpl;
let newtext;
while ((newtext = replaceDateVar(text, now)) != text) {
text = newtext;
}
while ((newtext = replaceFrontmatterVar(text, frontmatter)) != text) {
text = newtext;
}
text = text.replace(/{{imageNameKey}}/gm, data.imageNameKey).replace(/{{fileName}}/gm, data.fileName).replace(/{{dirName}}/gm, data.dirName).replace(/{{firstHeading}}/gm, data.firstHeading);
return text;
};
// src/main.ts
var DEFAULT_SETTINGS = {
imageNamePattern: "{{fileName}}",
dupNumberAtStart: false,
dupNumberDelimiter: "-",
dupNumberAlways: false,
autoRename: false,
handleAllAttachments: false,
excludeExtensionPattern: "",
disableRenameNotice: false
};
var PASTED_IMAGE_PREFIX = "Pasted image ";
var PasteImageRenamePlugin = class extends import_obsidian2.Plugin {
constructor() {
super(...arguments);
this.modals = [];
}
onload() {
return __async(this, null, function* () {
const pkg = require_package();
console.log(`Plugin loading: ${pkg.name} ${pkg.version} BUILD_ENV=${"production"}`);
yield this.loadSettings();
this.registerEvent(
this.app.vault.on("create", (file) => {
if (!(file instanceof import_obsidian2.TFile))
return;
const timeGapMs = new Date().getTime() - file.stat.ctime;
if (timeGapMs > 1e3)
return;
if (isMarkdownFile(file))
return;
if (isPastedImage(file)) {
debugLog("pasted image created", file);
this.startRenameProcess(file, this.settings.autoRename);
} else {
if (this.settings.handleAllAttachments) {
debugLog("handleAllAttachments for file", file);
if (this.testExcludeExtension(file)) {
debugLog("excluded file by ext", file);
return;
}
this.startRenameProcess(file, this.settings.autoRename);
}
}
})
);
const startBatchRenameProcess = () => {
this.openBatchRenameModal();
};
this.addCommand({
id: "batch-rename-embeded-files",
name: "Batch rename embeded files (in the current file)",
callback: startBatchRenameProcess
});
if (DEBUG) {
this.addRibbonIcon("wand-glyph", "Batch rename embeded files", startBatchRenameProcess);
}
const batchRenameAllImages = () => {
this.batchRenameAllImages();
};
this.addCommand({
id: "batch-rename-all-images",
name: "Batch rename all images instantly (in the current file)",
callback: batchRenameAllImages
});
if (DEBUG) {
this.addRibbonIcon("wand-glyph", "Batch rename all images instantly (in the current file)", batchRenameAllImages);
}
this.addSettingTab(new SettingTab(this.app, this));
});
}
startRenameProcess(file, autoRename = false) {
return __async(this, null, function* () {
const activeFile = this.getActiveFile();
if (!activeFile) {
new import_obsidian2.Notice("Error: No active file found.");
return;
}
const { stem, newName, isMeaningful } = this.generateNewName(file, activeFile);
debugLog("generated newName:", newName, isMeaningful);
if (!isMeaningful || !autoRename) {
this.openRenameModal(file, isMeaningful ? stem : "", activeFile.path);
return;
}
this.renameFile(file, newName, activeFile.path, true);
});
}
renameFile(file, inputNewName, sourcePath, replaceCurrentLine) {
return __async(this, null, function* () {
const { name: newName } = yield this.deduplicateNewName(inputNewName, file);
debugLog("deduplicated newName:", newName);
const originName = file.name;
const linkText = this.app.fileManager.generateMarkdownLink(file, sourcePath);
const newPath = path.join(file.parent.path, newName);
try {
yield this.app.fileManager.renameFile(file, newPath);
} catch (err) {
new import_obsidian2.Notice(`Failed to rename ${newName}: ${err}`);
throw err;
}
if (!replaceCurrentLine) {
return;
}
const newLinkText = this.app.fileManager.generateMarkdownLink(file, sourcePath);
debugLog("replace text", linkText, newLinkText);
const editor = this.getActiveEditor();
if (!editor) {
new import_obsidian2.Notice(`Failed to rename ${newName}: no active editor`);
return;
}
const cursor = editor.getCursor();
const line = editor.getLine(cursor.line);
const replacedLine = line.replace(linkText, newLinkText);
debugLog("current line -> replaced line", line, replacedLine);
editor.transaction({
changes: [
{
from: __spreadProps(__spreadValues({}, cursor), { ch: 0 }),
to: __spreadProps(__spreadValues({}, cursor), { ch: line.length }),
text: replacedLine
}
]
});
if (!this.settings.disableRenameNotice) {
new import_obsidian2.Notice(`Renamed ${originName} to ${newName}`);
}
});
}
openRenameModal(file, newName, sourcePath) {
const modal = new ImageRenameModal(
this.app,
file,
newName,
(confirmedName) => {
debugLog("confirmedName:", confirmedName);
this.renameFile(file, confirmedName, sourcePath, true);
},
() => {
this.modals.splice(this.modals.indexOf(modal), 1);
}
);
this.modals.push(modal);
modal.open();
debugLog("modals count", this.modals.length);
}
openBatchRenameModal() {
const activeFile = this.getActiveFile();
const modal = new ImageBatchRenameModal(
this.app,
activeFile,
(file, name) => __async(this, null, function* () {
yield this.renameFile(file, name, activeFile.path);
}),
() => {
this.modals.splice(this.modals.indexOf(modal), 1);
}
);
this.modals.push(modal);
modal.open();
}
batchRenameAllImages() {
return __async(this, null, function* () {
const activeFile = this.getActiveFile();
const fileCache = this.app.metadataCache.getFileCache(activeFile);
if (!fileCache || !fileCache.embeds)
return;
const extPatternRegex = /jpe?g|png|gif|tiff|webp/i;
for (const embed of fileCache.embeds) {
const file = this.app.metadataCache.getFirstLinkpathDest(embed.link, activeFile.path);
if (!file) {
console.warn("file not found", embed.link);
return;
}
const m0 = extPatternRegex.exec(file.extension);
if (!m0)
return;
const { newName, isMeaningful } = this.generateNewName(file, activeFile);
debugLog("generated newName:", newName, isMeaningful);
if (!isMeaningful) {
new import_obsidian2.Notice("Failed to batch rename images: the generated name is not meaningful");
break;
}
yield this.renameFile(file, newName, activeFile.path, false);
}
});
}
// returns a new name for the input file, with extension
generateNewName(file, activeFile) {
let imageNameKey = "";
let firstHeading = "";
let frontmatter;
const fileCache = this.app.metadataCache.getFileCache(activeFile);
if (fileCache) {
debugLog("frontmatter", fileCache.frontmatter);
frontmatter = fileCache.frontmatter;
imageNameKey = (frontmatter == null ? void 0 : frontmatter.imageNameKey) || "";
firstHeading = getFirstHeading(fileCache.headings);
} else {
console.warn("could not get file cache from active file", activeFile.name);
}
const stem = renderTemplate(
this.settings.imageNamePattern,
{
imageNameKey,
fileName: activeFile.basename,
dirName: activeFile.parent.name,
firstHeading
},
frontmatter
);
const meaninglessRegex = new RegExp(`[${this.settings.dupNumberDelimiter}\\s]`, "gm");
return {
stem,
newName: stem + "." + file.extension,
isMeaningful: stem.replace(meaninglessRegex, "") !== ""
};
}
// newName: foo.ext
deduplicateNewName(newName, file) {
return __async(this, null, function* () {
const dir = file.parent.path;
const listed = yield this.app.vault.adapter.list(dir);
debugLog("sibling files", listed);
const newNameExt = path.extension(newName), newNameStem = newName.slice(0, newName.length - newNameExt.length - 1), newNameStemEscaped = escapeRegExp(newNameStem), delimiter = this.settings.dupNumberDelimiter, delimiterEscaped = escapeRegExp(delimiter);
let dupNameRegex;
if (this.settings.dupNumberAtStart) {
dupNameRegex = new RegExp(
`^(?<number>\\d+)${delimiterEscaped}(?<name>${newNameStemEscaped})\\.${newNameExt}$`
);
} else {
dupNameRegex = new RegExp(
`^(?<name>${newNameStemEscaped})${delimiterEscaped}(?<number>\\d+)\\.${newNameExt}$`
);
}
debugLog("dupNameRegex", dupNameRegex);
const dupNameNumbers = [];
let isNewNameExist = false;
for (let sibling of listed.files) {
sibling = path.basename(sibling);
if (sibling == newName) {
isNewNameExist = true;
continue;
}
const m = dupNameRegex.exec(sibling);
if (!m)
continue;
dupNameNumbers.push(parseInt(m.groups.number));
}
if (isNewNameExist || this.settings.dupNumberAlways) {
const newNumber = dupNameNumbers.length > 0 ? Math.max(...dupNameNumbers) + 1 : 1;
if (this.settings.dupNumberAtStart) {
newName = `${newNumber}${delimiter}${newNameStem}.${newNameExt}`;
} else {
newName = `${newNameStem}${delimiter}${newNumber}.${newNameExt}`;
}
}
return {
name: newName,
stem: newName.slice(0, newName.length - newNameExt.length - 1),
extension: newNameExt
};
});
}
getActiveFile() {
const view = this.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
const file = view == null ? void 0 : view.file;
debugLog("active file", file == null ? void 0 : file.path);
return file;
}
getActiveEditor() {
const view = this.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
return view == null ? void 0 : view.editor;
}
onunload() {
this.modals.map((modal) => modal.close());
}
testExcludeExtension(file) {
const pattern = this.settings.excludeExtensionPattern;
if (!pattern)
return false;
return new RegExp(pattern).test(file.extension);
}
loadSettings() {
return __async(this, null, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __async(this, null, function* () {
yield this.saveData(this.settings);
});
}
};
function getFirstHeading(headings) {
if (headings && headings.length > 0) {
for (const heading of headings) {
if (heading.level === 1) {
return heading.heading;
}
}
}
return "";
}
function isPastedImage(file) {
if (file instanceof import_obsidian2.TFile) {
if (file.name.startsWith(PASTED_IMAGE_PREFIX)) {
return true;
}
}
return false;
}
function isMarkdownFile(file) {
if (file instanceof import_obsidian2.TFile) {
if (file.extension === "md") {
return true;
}
}
return false;
}
var ImageRenameModal = class extends import_obsidian2.Modal {
constructor(app, src, stem, renameFunc, onClose) {
super(app);
this.src = src;
this.stem = stem;
this.renameFunc = renameFunc;
this.onCloseExtra = onClose;
}
onOpen() {
this.containerEl.addClass("image-rename-modal");
const { contentEl, titleEl } = this;
titleEl.setText("Rename image");
const imageContainer = contentEl.createDiv({
cls: "image-container"
});
imageContainer.createEl("img", {
attr: {
src: this.app.vault.getResourcePath(this.src)
}
});
let stem = this.stem;
const ext = this.src.extension;
const getNewName = (stem2) => stem2 + "." + ext;
const getNewPath = (stem2) => path.join(this.src.parent.path, getNewName(stem2));
const infoET = createElementTree(contentEl, {
tag: "ul",
cls: "info",
children: [
{
tag: "li",
children: [
{
tag: "span",
text: "Origin path"
},
{
tag: "span",
text: this.src.path
}
]
},
{
tag: "li",
children: [
{
tag: "span",
text: "New path"
},
{
tag: "span",
text: getNewPath(stem)
}
]
}
]
});
const doRename = () => __async(this, null, function* () {
debugLog("doRename", `stem=${stem}`);
this.renameFunc(getNewName(stem));
});
const nameSetting = new import_obsidian2.Setting(contentEl).setName("New name").setDesc("Please input the new name for the image (without extension)").addText((text) => text.setValue(stem).onChange(
(value) => __async(this, null, function* () {
stem = sanitizer.filename(value);
infoET.children[1].children[1].el.innerText = getNewPath(stem);
})
));
const nameInputEl = nameSetting.controlEl.children[0];
nameInputEl.focus();
const nameInputState = lockInputMethodComposition(nameInputEl);
nameInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !nameInputState.lock) {
e.preventDefault();
if (!stem) {
errorEl.innerText = 'Error: "New name" could not be empty';
errorEl.style.display = "block";
return;
}
doRename();
this.close();
}
}));
const errorEl = contentEl.createDiv({
cls: "error",
attr: {
style: "display: none;"
}
});
new import_obsidian2.Setting(contentEl).addButton((button) => {
button.setButtonText("Rename").onClick(() => {
doRename();
this.close();
});
}).addButton((button) => {
button.setButtonText("Cancel").onClick(() => {
this.close();
});
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
this.onCloseExtra();
}
};
var imageNamePatternDesc = `
The pattern indicates how the new name should be generated.
Available variables:
- {{fileName}}: name of the active file, without ".md" extension.
- {{imageNameKey}}: this variable is read from the markdown file's frontmatter, from the same key "imageNameKey".
- {{DATE:$FORMAT}}: use "$FORMAT" to format the current date, "$FORMAT" must be a Moment.js format string, e.g. {{DATE:YYYY-MM-DD}}.
Here are some examples from pattern to image names (repeat in sequence), variables: fileName = "My note", imageNameKey = "foo":
- {{fileName}}: My note, My note-1, My note-2
- {{imageNameKey}}: foo, foo-1, foo-2
- {{imageNameKey}}-{{DATE:YYYYMMDD}}: foo-20220408, foo-20220408-1, foo-20220408-2
`;
var SettingTab = class extends import_obsidian2.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian2.Setting(containerEl).setName("Image name pattern").setDesc(imageNamePatternDesc).setClass("long-description-setting-item").addText((text) => text.setPlaceholder("{{imageNameKey}}").setValue(this.plugin.settings.imageNamePattern).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.imageNamePattern = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Duplicate number at start (or end)").setDesc(`If enabled, duplicate number will be added at the start as prefix for the image name, otherwise it will be added at the end as suffix for the image name.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.dupNumberAtStart).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberAtStart = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Duplicate number delimiter").setDesc(`The delimiter to generate the number prefix/suffix for duplicated names. For example, if the value is "-", the suffix will be like "-1", "-2", "-3", and the prefix will be like "1-", "2-", "3-". Only characters that are valid in file names are allowed.`).addText((text) => text.setValue(this.plugin.settings.dupNumberDelimiter).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberDelimiter = sanitizer.delimiter(value);
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Always add duplicate number").setDesc(`If enabled, duplicate number will always be added to the image name. Otherwise, it will only be added when the name is duplicated.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.dupNumberAlways).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberAlways = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Auto rename").setDesc(`By default, the rename modal will always be shown to confirm before renaming, if this option is set, the image will be auto renamed after pasting.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.autoRename).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.autoRename = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Handle all attachments").setDesc(`By default, the plugin only handles images that starts with "Pasted image " in name,
which is the prefix Obsidian uses to create images from pasted content.
If this option is set, the plugin will handle all attachments that are created in the vault.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.handleAllAttachments).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.handleAllAttachments = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Exclude extension pattern").setDesc(`This option is only useful when "Handle all attachments" is enabled.
Write a Regex pattern to exclude certain extensions from being handled. Only the first line will be used.`).setClass("single-line-textarea").addTextArea((text) => text.setPlaceholder("docx?|xlsx?|pptx?|zip|rar").setValue(this.plugin.settings.excludeExtensionPattern).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.excludeExtensionPattern = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Disable rename notice").setDesc(`Turn off this option if you don't want to see the notice when renaming images.
Note that Obsidian may display a notice when a link has changed, this option cannot disable that.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.disableRenameNotice).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.disableRenameNotice = value;
yield this.plugin.saveSettings();
})
));
}
};
@@ -0,0 +1,10 @@
{
"id": "obsidian-paste-image-rename",
"name": "Paste image rename",
"version": "1.6.1",
"minAppVersion": "0.12.0",
"description": "Rename pasted images and all the other attchments added to the vault",
"author": "Reorx",
"authorUrl": "https://github.com/reorx",
"isDesktopOnly": false
}
@@ -0,0 +1,79 @@
/* src/styles.css */
:root {
--shadow-color: 0deg 0% 0%;
--shadow-elevation-medium:
0.5px 0.5px 0.7px hsl(var(--shadow-color) / 0.14),
1.1px 1.1px 1.5px -0.9px hsl(var(--shadow-color) / 0.12),
2.4px 2.5px 3.3px -1.8px hsl(var(--shadow-color) / 0.1),
5.3px 5.6px 7.3px -2.7px hsl(var(--shadow-color) / 0.09),
11px 11.4px 15.1px -3.6px hsl(var(--shadow-color) / 0.07);
}
.image-rename-modal .modal {
width: 65%;
min-width: 600px;
}
.image-rename-modal .modal-content {
padding: 10px 5px;
}
.image-rename-modal .image-container {
display: flex;
justify-content: center;
}
.image-rename-modal .info {
padding: 10px 0;
color: var(--text-muted);
user-select: text;
}
.image-rename-modal .info li > span:nth-of-type(1) {
display: inline-block;
width: 6em;
margin-right: .5em;
}
.image-rename-modal .info li > span:nth-of-type(1):after {
content: ":";
float: right;
}
.image-rename-modal .image-container img {
display: block;
max-height: 300px;
box-shadow: var(--shadow-elevation-medium);
}
.image-rename-modal .setting-item-control input {
min-width: 300px;
}
.image-rename-modal .error {
border: 1px solid rgb(201, 90, 90);
color: rgb(134, 22, 22);
padding: 10px;
}
.image-rename-modal table {
font-size: .9em;
line-height: 1.8;
margin-bottom: 1.5em;
user-select: text;
}
.image-rename-modal table td {
padding-right: 1em;
}
.image-rename-modal table thead td {
font-weight: 700;
}
.image-rename-modal table tbody td .file-path {
font-size: .8em;
color: var(--text-faint);
line-height: 1;
}
.long-description-setting-item {
flex-wrap: wrap;
}
.long-description-setting-item .setting-item-description {
white-space: pre-wrap;
line-height: 1.3em;
}
.long-description-setting-item .setting-item-control {
padding-top: 10px;
}
.long-description-setting-item .setting-item-control input {
min-width: 300px;
width: 50%;
}
+7
View File
@@ -0,0 +1,7 @@
{
"deleteOption": "system-trash",
"logsModal": true,
"excludedFolders": "000-inbox",
"ribbonIcon": true,
"excludeSubfolders": true
}
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
{
"id": "oz-clear-unused-images",
"name": "Clear Unused Images",
"version": "1.1.1",
"minAppVersion": "0.11.13",
"description": "Clear the images that you are not using anymore in your markdown notes to save space.",
"author": "Ozan",
"authorUrl": "https://www.ozan.pl",
"fundingUrl": "https://ko-fi.com/ozante",
"isDesktopOnly": false
}
+10
View File
@@ -0,0 +1,10 @@
.unused-images-logs {
margin-bottom: 13px;
margin-top: 5px;
}
.unused-images-center-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
+194
View File
@@ -0,0 +1,194 @@
{
"choices": [
{
"id": "0462f0ba-4349-4531-b1a0-6634e5fc146f",
"name": "日常记录-闪念笔记",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/时间戳笔记.md",
"fileNameFormat": {
"enabled": true,
"format": "{{DATE:YYYYMMDDHHmmSS}}"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Increment the file name",
"setFileExistsBehavior": false,
"fileOpening": {
"location": "tab",
"direction": "vertical",
"focus": true,
"mode": "default"
}
},
{
"id": "eccc9792-8b8b-42bd-a20d-8c061ece98cf",
"name": "移动杭研-问题记录",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/移动杭研-问题记录.md",
"fileNameFormat": {
"enabled": true,
"format": "{{DATE:MMDD}}-{{value}}"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Increment the file name",
"setFileExistsBehavior": false,
"fileOpening": {
"location": "split",
"direction": "vertical",
"focus": true,
"mode": "default"
}
},
{
"id": "4ad23b51-d9fd-445e-aed8-f332e99f2350",
"name": "移动杭研-开发笔记",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/移动杭研-开发笔记.md",
"fileNameFormat": {
"enabled": true,
"format": "开发笔记"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Nothing",
"setFileExistsBehavior": true,
"fileOpening": {
"location": "split",
"direction": "vertical",
"focus": true,
"mode": "default"
}
}
],
"inputPrompt": "multi-line",
"persistInputPromptDrafts": true,
"useSelectionAsCaptureValue": true,
"devMode": false,
"templateFolderPath": "attachment/templates",
"announceUpdates": "all",
"version": "2.11.0",
"globalVariables": {},
"onePageInputEnabled": false,
"disableOnlineFeatures": true,
"enableRibbonIcon": true,
"showCaptureNotification": true,
"showInputCancellationNotification": false,
"enableTemplatePropertyTypes": false,
"dateAliases": {
"t": "today",
"tm": "tomorrow",
"yd": "yesterday",
"nw": "next week",
"nm": "next month",
"ny": "next year",
"lw": "last week",
"lm": "last month",
"ly": "last year"
},
"ai": {
"defaultModel": "Ask me",
"defaultSystemPrompt": "As an AI assistant within Obsidian, your primary goal is to help users manage their ideas and knowledge more effectively. Format your responses using Markdown syntax. Please use the [[Obsidian]] link format. You can write aliases for the links by writing [[Obsidian|the alias after the pipe symbol]]. To use mathematical notation, use LaTeX syntax. LaTeX syntax for larger equations should be on separate lines, surrounded with double dollar signs ($$). You can also inline math expressions by wrapping it in $ symbols. For example, use $$w_{ij}^{\text{new}}:=w_{ij}^{\text{current}}+etacdotdelta_jcdot x_{ij}$$ on a separate line, but you can write \"($eta$ = learning rate, $delta_j$ = error term, $x_{ij}$ = input)\" inline.",
"promptTemplatesFolderPath": "",
"showAssistant": true,
"providers": [
{
"name": "OpenAI",
"endpoint": "https://api.openai.com/v1",
"apiKey": "",
"models": [
{
"name": "gpt-3.5-turbo",
"maxTokens": 4096
},
{
"name": "gpt-3.5-turbo-16k",
"maxTokens": 16384
},
{
"name": "gpt-3.5-turbo-1106",
"maxTokens": 16385
},
{
"name": "gpt-4",
"maxTokens": 8192
},
{
"name": "gpt-4-32k",
"maxTokens": 32768
},
{
"name": "gpt-4-1106-preview",
"maxTokens": 128000
},
{
"name": "text-davinci-003",
"maxTokens": 4096
}
],
"modelSource": "auto"
}
]
},
"migrations": {
"migrateToMacroIDFromEmbeddedMacro": true,
"useQuickAddTemplateFolder": true,
"incrementFileNameSettingMoveToDefaultBehavior": true,
"mutualExclusionInsertAfterAndWriteToBottomOfFile": true,
"setVersionAfterUpdateModalRelease": true,
"addDefaultAIProviders": true,
"removeMacroIndirection": true,
"migrateFileOpeningSettings": true,
"setProviderModelDiscoveryMode": true,
"backfillFileOpeningDefaults": true,
"migrateProviderApiKeysToSecretStorage": true
}
}
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
{
"id": "quickadd",
"name": "QuickAdd",
"version": "2.11.0",
"minAppVersion": "1.11.4",
"description": "Quickly add new pages or content to your vault.",
"author": "Christian B. B. Houmann",
"authorUrl": "https://bagerbach.com",
"fundingUrl": "https://www.buymeacoffee.com/chhoumann",
"helpUrl": "https://quickadd.obsidian.guide/docs/",
"isDesktopOnly": false
}
File diff suppressed because one or more lines are too long
+211
View File
@@ -0,0 +1,211 @@
{
"recentFiles": [
{
"basename": "常用命令",
"path": "resource/常用命令.md"
},
{
"basename": "服务器-香港",
"path": "personal/服务器-香港.md"
},
{
"basename": "20260228151875",
"path": "000-Inbox/20260228151875.md"
},
{
"basename": "ibs-ai 项目 AI 对话流程",
"path": "000-inbox/ibs-ai 项目 AI 对话流程.md"
},
{
"basename": "20260228151875",
"path": "000-inbox/20260228151875.md"
},
{
"basename": "20260228121029",
"path": "000-inbox/20260228121029.md"
},
{
"basename": "React 工程师",
"path": "000-inbox/React 工程师.md"
},
{
"basename": "20260228160576",
"path": "000-Inbox/20260228160576.md"
},
{
"basename": "20260228121029",
"path": "000-Inbox/20260228121029.md"
},
{
"basename": "词性",
"path": "000-inbox/词性.md"
},
{
"basename": "开发笔记",
"path": "work/移动杭研/开发记录/7.18.0/开发笔记.md"
},
{
"basename": "Ubuntu 24.04 LTS ELK 8 安装指南",
"path": "resource/组件/Ubuntu 24.04 LTS ELK 8 安装指南.md"
},
{
"basename": "句子",
"path": "000-inbox/句子.md"
},
{
"basename": "20260227091585",
"path": "000-Inbox/20260227091585.md"
},
{
"basename": "20260227085218",
"path": "000-Inbox/20260227085218.md"
},
{
"basename": "Rime 快捷键",
"path": "resource/工具/Rime 快捷键.md"
},
{
"basename": "20260226205814",
"path": "000-Inbox/20260226205814.md"
},
{
"basename": "20260226171537",
"path": "000-Inbox/20260226171537.md"
},
{
"basename": "20260226100117",
"path": "000-Inbox/20260226100117.md"
},
{
"basename": "20260226102970",
"path": "000-Inbox/20260226102970.md"
},
{
"basename": "20260226143206",
"path": "000-Inbox/20260226143206.md"
},
{
"basename": "ubuntu",
"path": "resource/系统/ubuntu.md"
},
{
"basename": "服务器-华为",
"path": "personal/服务器-华为.md"
},
{
"basename": "20260225210630",
"path": "000-Inbox/20260225210630.md"
},
{
"basename": "tg-bot",
"path": "000-inbox/tg-bot.md"
},
{
"basename": "DNS 泄露问题",
"path": "resource/系统/网络/DNS 泄露问题.md"
},
{
"basename": "vim 快捷键与操作手册",
"path": "resource/系统/vim 快捷键与操作手册.md"
},
{
"basename": "OpenClaw",
"path": "resource/ai/OpenClaw.md"
},
{
"basename": "ibs-export",
"path": "work/移动杭研/业务梳理/ibs-export.md"
},
{
"basename": "20260223203842",
"path": "000-Inbox/20260223203842.md"
},
{
"basename": "Claude Code 配置文件",
"path": "resource/配置/Claude Code 配置文件.md"
},
{
"basename": "Claude Code 提示词",
"path": "resource/配置/Claude Code 提示词.md"
},
{
"basename": "20260211113769",
"path": "000-Inbox/20260211113769.md"
},
{
"basename": "Rime YAML Custom Patch 语法笔记",
"path": "resource/工具/Rime YAML Custom Patch 语法笔记.md"
},
{
"basename": "Rime 小狼毫",
"path": "resource/工具/Rime 小狼毫.md"
},
{
"basename": "HCDN-备忘录",
"path": "work/移动杭研/开发记录/7.17.0/HCDN-备忘录.md"
},
{
"basename": "domain_request 分支梳理 2",
"path": "work/移动杭研/开发记录/7.18.0/domain_request 分支梳理 2.md"
},
{
"basename": "domain_request 分支梳理",
"path": "work/移动杭研/开发记录/7.18.0/domain_request 分支梳理.md"
},
{
"basename": "域名配置需求工单-提单",
"path": "excalidraw/域名配置需求工单-提单.md"
},
{
"basename": "ESOP-域名配置需求-新增",
"path": "work/移动杭研/业务梳理/运营工单/ESOP-域名配置需求-新增.md"
},
{
"basename": "idea jvm",
"path": "resource/配置/idea jvm.md"
},
{
"basename": "20260208143789",
"path": "000-Inbox/20260208143789.md"
},
{
"basename": "20260207215002",
"path": "000-Inbox/20260207215002.md"
},
{
"basename": "20260207103531",
"path": "000-Inbox/20260207103531.md"
},
{
"basename": "20260206231116",
"path": "000-Inbox/20260206231116.md"
},
{
"basename": "开发笔记",
"path": "work/移动杭研/开发记录/7.17.0/开发笔记.md"
},
{
"basename": "20260206081367",
"path": "000-Inbox/20260206081367.md"
},
{
"basename": "信安业务流程及代码梳理",
"path": "work/移动杭研/业务梳理/信安信息/信安业务流程及代码梳理.md"
},
{
"basename": "域名配置需求工单-终止",
"path": "excalidraw/域名配置需求工单-终止.md"
},
{
"basename": "This is the prompt",
"path": "resource/ai/This is the prompt.md"
}
],
"omittedPaths": [
"^attachment/",
"^calendar/"
],
"omittedTags": [],
"updateOn": "file-open",
"omitBookmarks": false
}
File diff suppressed because one or more lines are too long
+16
View File
@@ -0,0 +1,16 @@
{
"id": "recent-files-obsidian",
"name": "Recent Files",
"version": "1.7.6",
"minAppVersion": "0.16.3",
"description": "List files by most recently opened",
"author": "Tony Grosinger",
"authorUrl": "https://grosinger.net",
"isDesktopOnly": false,
"fundingUrl": {
"Github Sponsor": "https://github.com/sponsors/tgrosinger",
"Buy me a Coffee": "https://buymeacoffee.com/tgrosinger",
"Paypal": "https://paypal.me/tgrosinger"
},
"donation": "https://buymeacoffee.com/tgrosinger"
}
+34
View File
@@ -0,0 +1,34 @@
.recent-files-file {
.tree-item-spacer {
flex-grow: 1;
}
}
.recent-files-title {
justify-content: flex-start;
align-items: unset;
}
.recent-files-file-delete {
justify-content: right;
display: none;
}
.recent-files-title:hover .recent-files-file-delete {
display: flex;
cursor: var(--cursor);
}
.recent-files-file-delete:hover {
color: var(--nav-item-color-hover);
}
.recent-files-donation {
width: 70%;
margin: 0 auto;
text-align: center;
}
.recent-files-donate-button {
margin: 10px;
}
+30
View File
@@ -0,0 +1,30 @@
{
"command_timeout": 5,
"templates_folder": "attachment/templates",
"templates_pairs": [
[
"",
""
]
],
"trigger_on_file_creation": true,
"auto_jump_to_cursor": true,
"enable_system_commands": false,
"shell_path": "",
"user_scripts_folder": "",
"enable_folder_templates": false,
"folder_templates": [],
"enable_file_templates": false,
"file_templates": [
{
"regex": ".*",
"template": ""
}
],
"syntax_highlighting": true,
"syntax_highlighting_mobile": false,
"enabled_templates_hotkeys": [],
"startup_templates": [],
"intellisense_render": 1,
"enable_ribbon_icon": true
}
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
{
"id": "templater-obsidian",
"name": "Templater",
"version": "2.18.1",
"description": "Create and use templates",
"minAppVersion": "1.5.0",
"author": "SilentVoid",
"authorUrl": "https://github.com/SilentVoid13",
"helpUrl": "https://silentvoid13.github.io/Templater/",
"isDesktopOnly": false
}
+226
View File
@@ -0,0 +1,226 @@
.templater_search {
width: calc(100% - 20px);
}
.templater_div {
border-top: 1px solid var(--background-modifier-border);
}
.templater_div > .setting-item {
border-top: none !important;
align-self: center;
}
.templater_div > .setting-item > .setting-item-control {
justify-content: space-around;
padding: 0;
width: 100%;
}
.templater_div
> .setting-item
> .setting-item-control
> .setting-editor-extra-setting-button {
align-self: center;
}
.templater_donating {
margin: 10px;
}
.templater_title {
margin: 0;
padding: 0;
margin-top: 5px;
text-align: center;
}
.templater_template {
align-self: center;
margin-left: 5px;
margin-right: 5px;
width: 70%;
}
.templater_cmd {
margin-left: 5px;
margin-right: 5px;
font-size: 14px;
width: 100%;
}
.templater_div2 > .setting-item {
align-content: center;
justify-content: center;
}
.templater-prompt-div,
.templater-multisuggester-div {
display: flex;
}
.templater-prompt-form {
display: flex;
flex-grow: 1;
}
.templater-prompt-input,
.templater-multisuggester-input {
flex-grow: 1;
}
.templater-button-div {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 1rem;
}
textarea.templater-prompt-input {
height: 10rem;
}
textarea.templater-prompt-input:focus {
border-color: var(--interactive-accent);
}
.templater-multisuggester-list {
margin: 1.5em 0;
}
.cm-s-obsidian .templater-command-bg {
left: 0px;
right: 0px;
background-color: var(--background-primary-alt);
}
.cm-s-obsidian .cm-templater-command {
font-size: 0.85em;
font-family: var(--font-monospace);
line-height: 1.3;
}
.cm-s-obsidian .templater-inline .cm-templater-command {
background-color: var(--background-primary-alt);
}
.cm-s-obsidian .cm-templater-command.cm-templater-opening-tag {
font-weight: bold;
}
.cm-s-obsidian .cm-templater-command.cm-templater-closing-tag {
font-weight: bold;
}
.cm-s-obsidian .cm-templater-command.cm-templater-interpolation-tag {
color: var(--code-property, #008bff);
}
.cm-s-obsidian .cm-templater-command.cm-templater-execution-tag {
color: var(--code-function, #c0d700);
}
.cm-s-obsidian .cm-templater-command.cm-keyword {
color: var(--code-keyword, #00a7aa);
font-weight: normal;
}
.cm-s-obsidian .cm-templater-command.cm-atom {
color: var(--code-normal, #f39b35);
}
.cm-s-obsidian .cm-templater-command.cm-value,
.cm-s-obsidian .cm-templater-command.cm-number,
.cm-s-obsidian .cm-templater-command.cm-type {
color: var(--code-value, #a06fca);
}
.cm-s-obsidian .cm-templater-command.cm-def,
.cm-s-obsidian .cm-templater-command.cm-type.cm-def {
color: var(--code-normal, var(--text-normal));
}
.cm-s-obsidian .cm-templater-command.cm-property,
.cm-s-obsidian .cm-templater-command.cm-property.cm-def,
.cm-s-obsidian .cm-templater-command.cm-attribute {
color: var(--code-function, #98e342);
}
.cm-s-obsidian .cm-templater-command.cm-variable,
.cm-s-obsidian .cm-templater-command.cm-variable-2,
.cm-s-obsidian .cm-templater-command.cm-variable-3,
.cm-s-obsidian .cm-templater-command.cm-meta {
color: var(--code-property, #d4d4d4);
}
.cm-s-obsidian .cm-templater-command.cm-callee,
.cm-s-obsidian .cm-templater-command.cm-operator,
.cm-s-obsidian .cm-templater-command.cm-qualifier,
.cm-s-obsidian .cm-templater-command.cm-builtin {
color: var(--code-operator, #fc4384);
}
.cm-s-obsidian .cm-templater-command.cm-tag {
color: var(--code-tag, #fc4384);
}
.cm-s-obsidian .cm-templater-command.cm-comment,
.cm-s-obsidian .cm-templater-command.cm-comment.cm-tag,
.cm-s-obsidian .cm-templater-command.cm-comment.cm-attribute {
color: var(--code-comment, #696d70);
}
.cm-s-obsidian .cm-templater-command.cm-string,
.cm-s-obsidian .cm-templater-command.cm-string-2 {
color: var(--code-string, #e6db74);
}
.cm-s-obsidian .cm-templater-command.cm-header,
.cm-s-obsidian .cm-templater-command.cm-hr {
color: var(--code-keyword, #da7dae);
}
.cm-s-obsidian .cm-templater-command.cm-link {
color: var(--code-normal, #696d70);
}
.cm-s-obsidian .cm-templater-command.cm-error {
border-bottom: 1px solid #c42412;
}
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
.CodeMirror-hint {
margin: 0;
padding: 0 4px;
border-radius: 2px;
white-space: pre;
color: black;
cursor: pointer;
}
li.CodeMirror-hint-active {
background: #08f;
color: white;
}
+8
View File
@@ -0,0 +1,8 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var $=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var O=(e,n)=>{for(var o in n)$(e,o,{get:n[o],enumerable:!0})},L=(e,n,o,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let u of I(n))!B.call(e,u)&&u!==o&&$(e,u,{get:()=>n[u],enumerable:!(i=b(n,u))||i.enumerable});return e};var j=e=>L($({},"__esModule",{value:!0}),e);var A={};O(A,{default:()=>x});module.exports=j(A);var c=require("obsidian");function T(e){return P(y(e).slice(0,-1))}function F(e,n){if(!e)return n;let o=y(e),i=y(n),u=o.findIndex((h,w)=>h!=i[w]),f=[];for(let h=u;h<o.length-1;h++)f.push("..");for(let h=u;h<i.length;h++)f.push(i[h]);return P(f)}function y(e){return e.split("/")}function P(e){return e.join("/")}var E=class extends c.Modal{constructor(n,o,i){super(n),this.content=o,this.onConfirm=i}onOpen(){let{contentEl:n}=this;n.createEl("h1",{text:"Update Releate Links Plugin"}),n.createEl("p",{text:this.content}),new c.Setting(n).addButton(o=>o.setButtonText("Yes").setCta().onClick(()=>{this.close(),this.onConfirm()})).addButton(o=>o.setButtonText("No").onClick(()=>{this.close()}))}onClose(){this.contentEl.empty()}},x=class extends c.Plugin{async onload(){let{app:n}=this,{metadataCache:o,vault:i}=n,u="This command will modify all links in the entire vault (not just the current file) to relative paths, and this action cannot be undone. It is recommended that you back up the vault in advance. Please confirm whether you want to execute the command.";this.addCommand({id:"update-all-relative-links",name:"Update all relative links",callback(){new E(n,u,()=>{let t=i.getMarkdownFiles().map(r=>f(r,!1));Promise.all(t).then(r=>{let s=r.filter(m=>m>0),a=s.reduce((m,C)=>m+C,0),l=s.length;new c.Notice(`Update ${a} links in ${l} file${l>1?"s":""}.`)}).catch(r=>{new c.Notice("Update links error, see console."),console.error(r)})}).open()}}),this.registerEvent(i.on("rename",(t,r)=>{var s;!r||!t.path.toLocaleLowerCase().endsWith(".md")||((s=t.parent)==null?void 0:s.path)===T(r)||t instanceof c.TFile&&setTimeout(()=>f(t,!0),100)}));async function f(t,r){var m,C;let s=o.getFileCache(t),l=[...(m=s==null?void 0:s.links)!=null?m:[],...(C=s==null?void 0:s.embeds)!=null?C:[]].map(({link:d,original:v})=>{var S;let g=d.replace(/#.*$/,"");if(!g)return null;let k=o.getFirstLinkpathDest(g,t.path);if(!k)return null;let p=((S=t.parent)==null?void 0:S.path)==="/"?k.path:F(t.path,k.path);if(g===p)return null;let U=h(v,g,p);return[v,U]}).filter(d=>d);if(!(l!=null&&l.length))return 0;try{let d=await i.read(t),v=l.reduce((k,p)=>(p==null?void 0:p.length)===2?k.replace(p[0],p[1]):k,d);await i.modify(t,v);let g=`Update ${l.length} links in ${t.path}.`;return console.log(g),r&&new c.Notice(g),l.length}catch(d){throw console.error(d),r&&new c.Notice("Update links error, see console."),d}}function h(t,r,s){let a=w(t,r,s,l=>l.replace(/ /g,"%20"));return t===a&&(a=w(t,r,s,encodeURI)),t===a&&(a=t.replace(/^(!?\[.*?\]).*$/,`$1(${encodeURI(s)})`)),a}function w(t,r,s,a){return t.replace(a(r),a(s))}}};
/* nosourcemap */
+10
View File
@@ -0,0 +1,10 @@
{
"id": "update-relative-links",
"name": "Update Relative Links",
"version": "2.1.4",
"minAppVersion": "0.15.0",
"description": "Update relative links.",
"author": "val",
"authorUrl": "https://github.com/val3344/obsidian-update-relative-links",
"isDesktopOnly": false
}
+13
View File
@@ -0,0 +1,13 @@
{
"queries": [
{
"createdAt": "2024/10/27 17:03:06",
"id": "202410271703062",
"pinnedAt": "2024/10/27 17:03:16",
"querystring": "[{\"type\":\"LIST\",\"value\":{\"operator\":\"IS\",\"value\":\"TODO\"},\"relation\":\"AND\"},{\"type\":\"TAG\",\"value\":{\"operator\":\"CONTAIN\",\"value\":\"日记/待办\"},\"relation\":\"OR\"}]",
"title": "任务",
"updatedAt": "2024/10/27 17:03:06",
"userId": "Thino"
}
]
}
+25
View File
@@ -0,0 +1,25 @@
/* === 颜色变量 === */
:root {
--h1-color: #172a4f;
--h2-color: #4a5c7a;
--h3-color: #6b7280;
--bold-color: var(--h1-color);
}
/* === 标题样式 === */
h1 {
color: var(--h1-color);
}
h2 {
color: var(--h2-color);
}
h3 {
color: var(--h3-color);
}
/* === 粗体样式 === */
div.cm-line span.cm-strong,
div p strong {
color: var(--bold-color) !important;
}
+5
View File
@@ -0,0 +1,5 @@
{
"showExistingOnly": false,
"showAttachments": true,
"showAllFileTypes": true
}
+3
View File
@@ -0,0 +1,3 @@
{
"folder": ""
}
+29
View File
@@ -0,0 +1,29 @@
{
"types": {
"aliases": "aliases",
"cssclasses": "multitext",
"tags": "tags",
"excalidraw-plugin": "text",
"excalidraw-export-transparent": "checkbox",
"excalidraw-mask": "checkbox",
"excalidraw-export-dark": "checkbox",
"excalidraw-export-padding": "number",
"excalidraw-export-pngscale": "number",
"excalidraw-export-embed-scene": "checkbox",
"excalidraw-link-prefix": "text",
"excalidraw-url-prefix": "text",
"excalidraw-link-brackets": "checkbox",
"excalidraw-onload-script": "text",
"excalidraw-linkbutton-opacity": "number",
"excalidraw-default-mode": "text",
"excalidraw-font": "text",
"excalidraw-font-color": "text",
"excalidraw-border-color": "text",
"excalidraw-css": "text",
"excalidraw-autoexport": "text",
"excalidraw-embeddable-theme": "text",
"excalidraw-open-md": "checkbox",
"excalidraw-embed-md": "checkbox",
"excalidraw-export-internal-links": "checkbox"
}
}
+278
View File
@@ -0,0 +1,278 @@
{
"main": {
"id": "5bcfdfb3906a10d9",
"type": "split",
"children": [
{
"id": "52c75605242e548c",
"type": "tabs",
"children": [
{
"id": "27e8f607bdc36b8c",
"type": "leaf",
"state": {
"type": "empty",
"state": {},
"icon": "lucide-file",
"title": "新标签页"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "35df6ec3039dcc8d",
"type": "split",
"children": [
{
"id": "6836caf2765d7139",
"type": "tabs",
"dimension": 69.27016645326505,
"children": [
{
"id": "c8718c0c63702202",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "文件列表"
}
},
{
"id": "b5a3cd3bad8e4921",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "搜索"
}
},
{
"id": "48045e844afa284a",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "书签"
}
}
]
},
{
"id": "729e97c586d5eaa9",
"type": "tabs",
"dimension": 30.72983354673495,
"children": [
{
"id": "4c0b938080320781",
"type": "leaf",
"state": {
"type": "recent-files",
"state": {},
"icon": "clock",
"title": "Recent Files"
}
}
]
}
],
"direction": "horizontal",
"width": 335.5
},
"right": {
"id": "ca733f6d5936ae40",
"type": "split",
"children": [
{
"id": "1f21045435bfa327",
"type": "tabs",
"dimension": 57.40291262135923,
"children": [
{
"id": "43a2e8e1d9201229",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "大纲"
}
},
{
"id": "d8fdece29a1174b9",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "000-Inbox/010-时间戳/20250516111714.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "20250516111714 的反向链接列表"
}
},
{
"id": "e4cd4c732455d6a5",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "出链"
}
},
{
"id": "937e0fc00804e8ba",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "标签"
}
},
{
"id": "313efe6d54d147a2",
"type": "leaf",
"state": {
"type": "all-properties",
"state": {
"sortOrder": "frequency",
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-archive",
"title": "添加笔记属性"
}
},
{
"id": "4e96951a5d10d474",
"type": "leaf",
"state": {
"type": "footnotes",
"state": {
"file": "900-Excalidraw/退回接口.md"
},
"icon": "lucide-file-signature",
"title": "脚注"
}
}
]
},
{
"id": "ea8a40d57ef90e62",
"type": "tabs",
"dimension": 42.59708737864077,
"children": [
{
"id": "499dbd491c6fb256",
"type": "leaf",
"state": {
"type": "calendar",
"state": {},
"icon": "calendar-with-checkmark",
"title": "Calendar"
}
}
]
}
],
"direction": "horizontal",
"width": 306.5
},
"left-ribbon": {
"hiddenItems": {
"command-palette:打开命令面板": false,
"switcher:打开快速切换": false,
"graph:查看关系图谱": false,
"daily-notes:打开/创建今天的日记": false,
"bases:新建数据库": false,
"obsidian-excalidraw-plugin:新建绘图文件": false,
"templater-obsidian:Templater": false,
"quickadd:QuickAdd": false,
"oz-clear-unused-images:Clear Unused Images": false
}
},
"active": "27e8f607bdc36b8c",
"lastOpenFiles": [
"resource/常用命令.md",
"personal/服务器-香港.md",
"calendar/diary/2026-02-28.md",
"calendar/diary/2026-02-27.md",
"000-Inbox/20260228151875.md",
"000-inbox/ibs-ai 项目 AI 对话流程.md",
"000-inbox/20260228151875.md",
"000-inbox/20260228121029.md",
"000-inbox/React 工程师.md",
"000-Inbox/20260228160576.md",
"attachment/Pasted image 20260228121021.png",
"attachment/Pasted image 20260228121011.png",
"attachment/Pasted image 20260228121002.png",
"000-Inbox/20260228121029.md",
"calendar/diary/2026-02-26.md",
"000-inbox/词性.md",
"work/移动杭研/开发记录/7.18.0/开发笔记.md",
"resource/组件/Ubuntu 24.04 LTS ELK 8 安装指南.md",
"000-inbox/20260226171537.md",
"000-inbox/句子.md",
"000-inbox/20260226205814.md",
"000-Inbox/20260227091585.md",
"000-Inbox/20260227085218.md",
"resource/工具/Rime 快捷键.md",
"000-Inbox/20260226205814.md",
"000-Inbox/20260226171537.md",
"calendar/diary/2026-02-05.md",
"calendar/diary/2026-02-11.md",
"calendar/diary/2026-02-09.md",
"attachment/images-uuid/64be7a370c2241658123dec75afa8ebb.png",
"attachment/images-paste/image-20260206105036743.png",
"resource/工具",
"attachment/images-paste/image-20260206105528982.png",
"attachment/image-20260130172212583.png",
"attachment/image-20260130171118370.png",
"attachment/Pasted image 20260129215401.png",
"attachment/images-paste/image-20260125202524521.png",
"personal/家人/小杨-年报-AI",
"未命名",
"resource/脚本",
"work/移动杭研/开发记录/7.18.0",
"attachment/霞鹜文楷-Mono-Bold.ttf",
"attachment/霞鹜文楷-Mono-Regular.ttf",
"excalidraw/fonts",
"resource/配置",
"gitleaks.toml"
]
}
+4
View File
@@ -0,0 +1,4 @@
{
"workspaces": {},
"active": "1-左右分屏-源码、阅读"
}
+5
View File
@@ -0,0 +1,5 @@
{
"folder": "000-Inbox",
"template": "100-Attachment/templates/时间戳笔记",
"format": ""
}