vault backup: 2026-02-21 15:59:55

This commit is contained in:
2026-02-21 15:59:55 +01:00
parent c410008d31
commit 4e687e66bf
40 changed files with 29792 additions and 161 deletions

6
.gitignore vendored
View File

@@ -1 +1,5 @@
/.obsidian/
# Ignorer les réglages locaux d'Obsidian (thème, plugins activés par l'utilisateur)
.obsidian/workspace.json
.obsidian/workspace-mobile.json
# Ignorer les fichiers système
.DS_Store

11
.obsidian/app.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"alwaysUpdateLinks": true,
"promptDelete": false,
"uriCallbacks": true,
"newFileLocation": "folder",
"newFileFolderPath": "notes",
"attachmentFolderPath": "static",
"showUnsupportedFiles": true,
"trashOption": "local",
"useMarkdownLinks": true
}

4
.obsidian/appearance.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"cssTheme": "",
"theme": "obsidian"
}

3
.obsidian/bookmarks.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"items": []
}

8
.obsidian/community-plugins.json vendored Normal file
View File

@@ -0,0 +1,8 @@
[
"obsidian-git",
"templater-obsidian",
"dataview",
"find-unlinked-files",
"obsidian-importer",
"obsidian-linter"
]

33
.obsidian/core-plugins.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"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": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}

4
.obsidian/daily-notes.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"format": "YYYY/MM/DD",
"template": "references/modeles/daily_notes"
}

22
.obsidian/graph.json vendored Normal file
View File

@@ -0,0 +1,22 @@
{
"collapse-filter": true,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 1,
"close": true
}

27
.obsidian/plugins/dataview/data.json vendored Normal file
View File

@@ -0,0 +1,27 @@
{
"renderNullAs": "\\-",
"taskCompletionTracking": false,
"taskCompletionUseEmojiShorthand": false,
"taskCompletionText": "completion",
"taskCompletionDateFormat": "yyyy-MM-dd",
"recursiveSubTaskCompletion": false,
"warnOnEmptyResult": true,
"refreshEnabled": true,
"refreshInterval": 2500,
"defaultDateFormat": "MMMM dd, yyyy",
"defaultDateTimeFormat": "h:mm a - MMMM dd, yyyy",
"maxRecursiveRenderDepth": 4,
"tableIdColumnName": "File",
"tableGroupColumnName": "Group",
"showResultCount": true,
"allowHtml": true,
"inlineQueryPrefix": "=",
"inlineJsQueryPrefix": "$=",
"inlineQueriesInCodeblocks": true,
"enableInlineDataview": true,
"enableDataviewJs": true,
"enableInlineDataviewJs": true,
"prettyRenderInlineFields": true,
"prettyRenderInlineFieldsInLivePreview": true,
"dataviewJsKeyword": "dataviewjs"
}

20876
.obsidian/plugins/dataview/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
{
"id": "dataview",
"name": "Dataview",
"version": "0.5.68",
"minAppVersion": "0.13.11",
"description": "Complex data views for the data-obsessed.",
"author": "Michael Brenan <blacksmithgu@gmail.com>",
"authorUrl": "https://github.com/blacksmithgu",
"helpUrl": "https://blacksmithgu.github.io/obsidian-dataview/",
"isDesktopOnly": false
}

141
.obsidian/plugins/dataview/styles.css vendored Normal file
View File

@@ -0,0 +1,141 @@
.block-language-dataview {
overflow-y: auto;
}
/*****************/
/** Table Views **/
/*****************/
/* List View Default Styling; rendered internally as a table. */
.table-view-table {
width: 100%;
}
.table-view-table > thead > tr, .table-view-table > tbody > tr {
margin-top: 1em;
margin-bottom: 1em;
text-align: left;
}
.table-view-table > tbody > tr:hover {
background-color: var(--table-row-background-hover);
}
.table-view-table > thead > tr > th {
font-weight: 700;
font-size: larger;
border-top: none;
border-left: none;
border-right: none;
border-bottom: solid;
max-width: 100%;
}
.table-view-table > tbody > tr > td {
text-align: left;
border: none;
font-weight: 400;
max-width: 100%;
}
.table-view-table ul, .table-view-table ol {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Rendered value styling for any view. */
.dataview-result-list-root-ul {
padding: 0em !important;
margin: 0em !important;
}
.dataview-result-list-ul {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Generic grouping styling. */
.dataview.result-group {
padding-left: 8px;
}
/*******************/
/** Inline Fields **/
/*******************/
.dataview.inline-field-key {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-primary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-standalone-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
/***************/
/** Task View **/
/***************/
.dataview.task-list-item, .dataview.task-list-basic-item {
margin-top: 3px;
margin-bottom: 3px;
transition: 0.4s;
}
.dataview.task-list-item:hover, .dataview.task-list-basic-item:hover {
background-color: var(--text-selection);
box-shadow: -40px 0 0 var(--text-selection);
cursor: pointer;
}
/*****************/
/** Error Views **/
/*****************/
div.dataview-error-box {
width: 100%;
min-height: 150px;
display: flex;
align-items: center;
justify-content: center;
border: 4px dashed var(--background-secondary);
}
.dataview-error-message {
color: var(--text-muted);
text-align: center;
}
/*************************/
/** Additional Metadata **/
/*************************/
.dataview.small-text {
font-size: smaller;
color: var(--text-muted);
margin-left: 3px;
}
.dataview.small-text::before {
content: "(";
}
.dataview.small-text::after {
content: ")";
}

View File

@@ -0,0 +1,907 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source visit the plugins github repository (https://github.com/Vinzent03/obsidian-advanced-uri)
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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);
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => FindOrphanedFilesPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian4 = require("obsidian");
// src/deleteFilesModal.ts
var import_obsidian = require("obsidian");
var DeleteFilesModal = class extends import_obsidian.Modal {
constructor(app, filesToDelete) {
super(app);
this.filesToDelete = filesToDelete;
}
onOpen() {
let { contentEl, titleEl } = this;
titleEl.setText(
"Move " + this.filesToDelete.length + " files to system trash?"
);
contentEl.createEl("button", { text: "Cancel" }).addEventListener("click", () => this.close());
contentEl.setAttr("margin", "auto");
contentEl.createEl("button", {
cls: "mod-cta",
text: "Confirm"
}).addEventListener("click", async () => {
for (const file of this.filesToDelete) {
await this.app.vault.trash(file, true);
}
this.close();
});
}
onClose() {
let { contentEl } = this;
contentEl.empty();
}
};
// src/settingsTab.ts
var import_obsidian2 = require("obsidian");
var SettingsTab = class extends import_obsidian2.PluginSettingTab {
constructor(app, plugin, defaultSettings) {
super(app, plugin);
this.defaultSettings = defaultSettings;
this.plugin = plugin;
}
// Add trailing slash to catch files named like the directory. See https://github.com/Vinzent03/find-unlinked-files/issues/24
formatPath(path, addDirectorySlash) {
if (path.length == 0)
return path;
path = (0, import_obsidian2.normalizePath)(path);
if (addDirectorySlash)
return path + "/";
else
return path;
}
display() {
let { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: this.plugin.manifest.name });
containerEl.createEl("h4", {
text: "Settings for finding orphaned files"
});
new import_obsidian2.Setting(containerEl).setName("Open output file").addToggle(
(cb) => cb.setValue(this.plugin.settings.openOutputFile).onChange((value) => {
this.plugin.settings.openOutputFile = value;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Output file name").setDesc(
"Set name of output file (without file extension). Make sure no file exists with this name because it will be overwritten! If the name is empty, the default name is set."
).addText(
(cb) => cb.onChange((value) => {
if (value.length == 0) {
this.plugin.settings.outputFileName = this.defaultSettings.outputFileName;
} else {
this.plugin.settings.outputFileName = value;
}
this.plugin.saveSettings();
}).setValue(this.plugin.settings.outputFileName)
);
new import_obsidian2.Setting(containerEl).setName("Disable working links").setDesc(
"Indent lines to disable the link and to clean up the graph view"
).addToggle(
(cb) => cb.onChange((value) => {
this.plugin.settings.disableWorkingLinks = value;
this.plugin.saveSettings();
}).setValue(this.plugin.settings.disableWorkingLinks)
);
new import_obsidian2.Setting(containerEl).setName("Exclude files in the given directories").setDesc(
"Enable to exclude files in the given directories. Disable to only include files in the given directories"
).addToggle(
(cb) => cb.setValue(this.plugin.settings.ignoreDirectories).onChange((value) => {
this.plugin.settings.ignoreDirectories = value;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Directories").setDesc("Add each directory path in a new line").addTextArea(
(cb) => cb.setPlaceholder("Directory/Subdirectory").setValue(
this.plugin.settings.directoriesToIgnore.join("\n")
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, true));
this.plugin.settings.directoriesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude files").setDesc("Add each file path in a new line (with file extension!)").addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(this.plugin.settings.filesToIgnore.join("\n")).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.filesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude links").setDesc(
"Exclude files, which contain the given file as link. Add each file path in a new line (with file extension!). Set it to `*` to exclude files with links."
).addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(this.plugin.settings.linksToIgnore.join("\n")).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.linksToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude files with the given filetypes").setDesc(
"Enable to exclude files with the given filetypes. Disable to only include files with the given filetypes"
).addToggle(
(cb) => cb.setValue(this.plugin.settings.ignoreFileTypes).onChange((value) => {
this.plugin.settings.ignoreFileTypes = value;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("File types").setDesc("Effect depends on toggle above").addTextArea(
(cb) => cb.setPlaceholder("docx,txt").setValue(this.plugin.settings.fileTypesToIgnore.join(",")).onChange((value) => {
let extensions = value.trim().split(",");
this.plugin.settings.fileTypesToIgnore = extensions;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude tags").setDesc(
"Exclude files, which contain the given tag. Add each tag separated by comma (without `#`)"
).addTextArea(
(cb) => cb.setPlaceholder("todo,unfinished").setValue(this.plugin.settings.tagsToIgnore.join(",")).onChange((value) => {
let tags = value.trim().split(",");
this.plugin.settings.tagsToIgnore = tags;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Filetypes to delete per command. See README.").setDesc(
"Add each filetype separated by comma. Set to `*` to delete all files."
).addTextArea(
(cb) => cb.setPlaceholder("jpg,png").setValue(this.plugin.settings.fileTypesToDelete.join(",")).onChange((value) => {
let extensions = value.trim().split(",");
this.plugin.settings.fileTypesToDelete = extensions;
this.plugin.saveSettings();
})
);
containerEl.createEl("h4", {
text: "Settings for finding broken links"
});
new import_obsidian2.Setting(containerEl).setName("Output file name").setDesc(
"Set name of output file (without file extension). Make sure no file exists with this name because it will be overwritten! If the name is empty, the default name is set."
).addText(
(cb) => cb.onChange((value) => {
if (value.length == 0) {
this.plugin.settings.unresolvedLinksOutputFileName = this.defaultSettings.unresolvedLinksOutputFileName;
} else {
this.plugin.settings.unresolvedLinksOutputFileName = value;
}
this.plugin.saveSettings();
}).setValue(
this.plugin.settings.unresolvedLinksOutputFileName
)
);
new import_obsidian2.Setting(containerEl).setName("Exclude files in the given directories").setDesc(
"Enable to exclude files in the given directories. Disable to only include files in the given directories"
).addToggle(
(cb) => cb.setValue(
this.plugin.settings.unresolvedLinksIgnoreDirectories
).onChange((value) => {
this.plugin.settings.unresolvedLinksIgnoreDirectories = value;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Directories").setDesc("Add each directory path in a new line").addTextArea(
(cb) => cb.setPlaceholder("Directory/Subdirectory").setValue(
this.plugin.settings.unresolvedLinksDirectoriesToIgnore.join(
"\n"
)
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, true));
this.plugin.settings.unresolvedLinksDirectoriesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude files").setDesc(
"Exclude links in the specified file. Add each file path in a new line (with file extension!)"
).addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(
this.plugin.settings.unresolvedLinksFilesToIgnore.join(
"\n"
)
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.unresolvedLinksFilesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude links").setDesc(
"Exclude files, which contain the given file as link. Add each file path in a new line (with file extension!). Set it to `*` to exclude files with links."
).addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(
this.plugin.settings.unresolvedLinksLinksToIgnore.join(
"\n"
)
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.unresolvedLinksLinksToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude filetypes").setDesc(
"Exclude links with the specified filetype. Add each filetype separated by comma"
).addTextArea(
(cb) => cb.setPlaceholder("docx,txt").setValue(
this.plugin.settings.unresolvedLinksFileTypesToIgnore.join(
","
)
).onChange((value) => {
let extensions = value.trim().split(",");
this.plugin.settings.unresolvedLinksFileTypesToIgnore = extensions;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude tags").setDesc(
"Exclude links in files, which contain the given tag. Add each tag separated by comma (without `#`)"
).addTextArea(
(cb) => cb.setPlaceholder("todo,unfinished").setValue(
this.plugin.settings.unresolvedLinksTagsToIgnore.join(
","
)
).onChange((value) => {
let tags = value.trim().split(",");
this.plugin.settings.unresolvedLinksTagsToIgnore = tags;
this.plugin.saveSettings();
})
);
containerEl.createEl("h4", {
text: "Settings for finding files without tags"
});
new import_obsidian2.Setting(containerEl).setName("Output file name").setDesc(
"Set name of output file (without file extension). Make sure no file exists with this name because it will be overwritten! If the name is empty, the default name is set."
).addText(
(cb) => cb.onChange((value) => {
if (value.length == 0) {
this.plugin.settings.withoutTagsOutputFileName = this.defaultSettings.withoutTagsOutputFileName;
} else {
this.plugin.settings.withoutTagsOutputFileName = value;
}
this.plugin.saveSettings();
}).setValue(this.plugin.settings.withoutTagsOutputFileName)
);
new import_obsidian2.Setting(containerEl).setName("Exclude files").setDesc(
"Exclude the specific files. Add each file path in a new line (with file extension!)"
).addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(
this.plugin.settings.withoutTagsFilesToIgnore.join("\n")
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.withoutTagsFilesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude directories").setDesc(
"Exclude files in the specified directories. Add each directory path in a new line"
).addTextArea(
(cb) => cb.setPlaceholder("Directory/Subdirectory").setValue(
this.plugin.settings.withoutTagsDirectoriesToIgnore.join(
"\n"
)
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, true));
this.plugin.settings.withoutTagsDirectoriesToIgnore = paths;
this.plugin.saveSettings();
})
);
containerEl.createEl("h4", {
text: "Settings for finding empty files"
});
new import_obsidian2.Setting(containerEl).setName("Output file name").setDesc(
"Set name of output file (without file extension). Make sure no file exists with this name because it will be overwritten! If the name is empty, the default name is set."
).addText(
(cb) => cb.onChange((value) => {
if (value.length == 0) {
this.plugin.settings.emptyFilesOutputFileName = this.defaultSettings.emptyFilesOutputFileName;
} else {
this.plugin.settings.emptyFilesOutputFileName = value;
}
this.plugin.saveSettings();
}).setValue(this.plugin.settings.emptyFilesOutputFileName)
);
new import_obsidian2.Setting(containerEl).setName("Exclude files in the given directories").setDesc(
"Enable to exclude files in the given directories. Disable to only include files in the given directories"
).addToggle(
(cb) => cb.setValue(this.plugin.settings.emptyFilesIgnoreDirectories).onChange((value) => {
this.plugin.settings.emptyFilesIgnoreDirectories = value;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Directories").setDesc("Add each directory path in a new line").addTextArea(
(cb) => cb.setPlaceholder("Directory/Subdirectory").setValue(
this.plugin.settings.emptyFilesDirectories.join("\n")
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, true));
this.plugin.settings.emptyFilesDirectories = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Exclude files").setDesc("Add each file path in a new line (with file extension!)").addTextArea(
(cb) => cb.setPlaceholder("Directory/file.md").setValue(
this.plugin.settings.emptyFilesFilesToIgnore.join("\n")
).onChange((value) => {
let paths = value.trim().split("\n").map((value2) => this.formatPath(value2, false));
this.plugin.settings.emptyFilesFilesToIgnore = paths;
this.plugin.saveSettings();
})
);
new import_obsidian2.Setting(containerEl).setName("Donate").setDesc(
"If you like this Plugin, consider donating to support continued development."
).addButton((bt) => {
bt.buttonEl.outerHTML = "<a href='https://ko-fi.com/F1F195IQ5' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi3.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>";
});
}
};
// src/utils.ts
var import_obsidian3 = require("obsidian");
var Utils = class {
/**
* Checks for the given settings. Is used for `Find orphaned files` and `Find broken links`
* @param app
* @param filePath
* @param tagsToIgnore
* @param linksToIgnore
* @param directoriesToIgnore
* @param filesToIgnore
* @param ignoreDirectories
*/
constructor(app, filePath, tagsToIgnore, linksToIgnore, directoriesToIgnore, filesToIgnore, ignoreDirectories = true, dir) {
this.app = app;
this.filePath = filePath;
this.tagsToIgnore = tagsToIgnore;
this.linksToIgnore = linksToIgnore;
this.directoriesToIgnore = directoriesToIgnore;
this.filesToIgnore = filesToIgnore;
this.ignoreDirectories = ignoreDirectories;
this.dir = dir;
this.fileCache = app.metadataCache.getCache(filePath);
}
hasTagsToIgnore() {
const tags = (0, import_obsidian3.getAllTags)(this.fileCache);
return (tags == null ? void 0 : tags.find(
(tag) => this.tagsToIgnore.contains(tag.substring(1))
)) !== void 0;
}
hasLinksToIgnore() {
var _a, _b;
if ((((_a = this.fileCache) == null ? void 0 : _a.embeds) != null || ((_b = this.fileCache) == null ? void 0 : _b.links) != null) && this.linksToIgnore[0] == "*") {
return true;
}
return (0, import_obsidian3.iterateCacheRefs)(this.fileCache, (cb) => {
var _a2;
const link = (_a2 = this.app.metadataCache.getFirstLinkpathDest(
cb.link,
this.filePath
)) == null ? void 0 : _a2.path;
return this.linksToIgnore.contains(link);
});
}
checkDirectory() {
if (this.dir) {
if (!this.filePath.startsWith(this.dir)) {
return true;
}
}
const contains = this.directoriesToIgnore.find(
(value) => value.length != 0 && this.filePath.startsWith(value)
) !== void 0;
if (this.ignoreDirectories) {
return contains;
} else {
return !contains;
}
}
isFileToIgnore() {
return this.filesToIgnore.contains(this.filePath);
}
shouldIgnoreFile() {
return this.hasTagsToIgnore() || this.hasLinksToIgnore() || this.checkDirectory() || this.isFileToIgnore();
}
/**
* Writes the text to the file and opens the file in a new pane if it is not opened yet
* @param app
* @param outputFileName name of the output file
* @param text data to be written to the file
*/
static async writeAndOpenFile(app, outputFileName, text, openFile) {
await app.vault.adapter.write(outputFileName, text);
if (!openFile)
return;
let fileIsAlreadyOpened = false;
app.workspace.iterateAllLeaves((leaf) => {
if (leaf.getDisplayText() != "" && outputFileName.startsWith(leaf.getDisplayText())) {
fileIsAlreadyOpened = true;
}
});
if (!fileIsAlreadyOpened) {
const newPane = app.workspace.getLeavesOfType("empty").length == 0;
if (newPane) {
app.workspace.openLinkText(outputFileName, "/", true);
} else {
const file = app.vault.getAbstractFileByPath(outputFileName);
if (file instanceof import_obsidian3.TFile) {
await app.workspace.getLeavesOfType("empty")[0].openFile(file);
} else {
app.workspace.openLinkText(outputFileName, "/", true);
}
}
}
}
};
// src/main.ts
var DEFAULT_SETTINGS = {
outputFileName: "orphaned files output",
disableWorkingLinks: false,
directoriesToIgnore: [],
filesToIgnore: [],
fileTypesToIgnore: [],
linksToIgnore: [],
tagsToIgnore: [],
fileTypesToDelete: [],
ignoreFileTypes: true,
ignoreDirectories: true,
unresolvedLinksIgnoreDirectories: true,
unresolvedLinksOutputFileName: "broken links output",
unresolvedLinksDirectoriesToIgnore: [],
unresolvedLinksFilesToIgnore: [],
unresolvedLinksFileTypesToIgnore: [],
unresolvedLinksLinksToIgnore: [],
unresolvedLinksTagsToIgnore: [],
withoutTagsDirectoriesToIgnore: [],
withoutTagsFilesToIgnore: [],
withoutTagsOutputFileName: "files without tags",
emptyFilesOutputFileName: "empty files",
emptyFilesDirectories: [],
emptyFilesFilesToIgnore: [],
emptyFilesIgnoreDirectories: true,
openOutputFile: true
};
var FindOrphanedFilesPlugin = class extends import_obsidian4.Plugin {
constructor() {
super(...arguments);
this.findExtensionRegex = /(\.[^.]+)$/;
}
async onload() {
console.log("loading " + this.manifest.name + " plugin");
await this.loadSettings();
this.addCommand({
id: "find-unlinked-files",
name: "Find orphaned files",
callback: () => this.findOrphanedFiles()
});
this.addCommand({
id: "find-unresolved-link",
name: "Find broken links",
callback: () => this.findBrokenLinks()
});
this.addCommand({
id: "delete-unlinked-files",
name: "Delete orphaned files with certain extension. See README",
callback: () => this.deleteOrphanedFiles()
});
this.addCommand({
id: "create-files-of-broken-links",
name: "Create files of broken links",
callback: () => this.createFilesOfBrokenLinks()
});
this.addCommand({
id: "find-files-without-tags",
name: "Find files without tags",
callback: () => this.findFilesWithoutTags()
});
this.addCommand({
id: "find-empty-files",
name: "Find empty files",
callback: () => this.findEmptyFiles()
});
this.addCommand({
id: "delete-empty-files",
name: "Delete empty files",
callback: () => this.deleteEmptyFiles()
});
this.addSettingTab(new SettingsTab(this.app, this, DEFAULT_SETTINGS));
this.app.workspace.on("file-menu", (menu, file, _, __) => {
if (file instanceof import_obsidian4.TFolder) {
menu.addItem((cb) => {
cb.setIcon("search");
cb.setTitle("Find orphaned files");
cb.onClick((_2) => {
this.findOrphanedFiles(file.path + "/");
});
});
}
});
}
async createFilesOfBrokenLinks() {
var _a, _b;
if (!await this.app.vault.adapter.exists(
this.settings.unresolvedLinksOutputFileName + ".md"
)) {
new import_obsidian4.Notice(
"Can't find file - Please run the `Find broken files' command before"
);
return;
}
const links = (_a = this.app.metadataCache.getCache(
this.settings.unresolvedLinksOutputFileName + ".md"
)) == null ? void 0 : _a.links;
if (!links) {
new import_obsidian4.Notice("No broken links found");
return;
}
const filesToCreate = [];
for (const link of links) {
const file = this.app.metadataCache.getFirstLinkpathDest(
link.link,
"/"
);
if (file)
continue;
const foundType = (_b = this.findExtensionRegex.exec(link.link)) == null ? void 0 : _b[0];
if ((foundType != null ? foundType : ".md") == ".md") {
if (foundType) {
filesToCreate.push(link.link);
} else {
filesToCreate.push(link.link + ".md");
}
}
}
if (filesToCreate) {
for (const file of filesToCreate) {
await this.app.vault.create(file, "");
}
}
}
async findEmptyFiles() {
var _a;
const files = this.app.vault.getFiles();
const emptyFiles = [];
for (const file of files) {
if (new Utils(
this.app,
file.path,
[],
[],
this.settings.emptyFilesDirectories,
this.settings.emptyFilesFilesToIgnore,
this.settings.emptyFilesIgnoreDirectories
).shouldIgnoreFile()) {
continue;
}
const content = await this.app.vault.read(file);
const trimmedContent = content.trim();
if (!trimmedContent) {
emptyFiles.push(file);
}
const cache = this.app.metadataCache.getFileCache(file);
const frontmatter = cache == null ? void 0 : cache.frontmatter;
if (frontmatter) {
const lines = content.trimRight().split("\n").length;
if (((_a = cache.frontmatterPosition) != null ? _a : frontmatter.position).end.line == lines - 1) {
emptyFiles.push(file);
}
}
}
let prefix;
if (this.settings.disableWorkingLinks)
prefix = " ";
else
prefix = "";
const text = emptyFiles.map((file) => `${prefix}- [[${file.path}]]`).join("\n");
Utils.writeAndOpenFile(
this.app,
this.settings.emptyFilesOutputFileName + ".md",
text,
this.settings.openOutputFile
);
}
async findOrphanedFiles(dir) {
const startTime = Date.now();
const outFileName = this.settings.outputFileName + ".md";
let outFile = null;
const allFiles = this.app.vault.getFiles();
const markdownFiles = this.app.vault.getMarkdownFiles();
const canvasFiles = allFiles.filter(
(file) => file.extension === "canvas"
);
const links = /* @__PURE__ */ new Set();
const findLinkInTextRegex = /\[\[(.*?)\]\]|\[.*?\]\((.*?)\)/g;
const canvasParsingPromises = canvasFiles.map(
async (canvasFile) => {
var _a;
const canvasFileContent = JSON.parse(
await this.app.vault.cachedRead(canvasFile) || "{}"
);
(_a = canvasFileContent.nodes) == null ? void 0 : _a.forEach((node) => {
var _a2;
let linkTexts = [];
if (node.type === "file") {
linkTexts.push(node.file);
} else if (node.type === "text") {
let match;
while ((match = findLinkInTextRegex.exec(node.text)) !== null) {
linkTexts.push((_a2 = match[1]) != null ? _a2 : match[2]);
}
} else {
return;
}
linkTexts.forEach((linkText) => {
const targetFile = this.app.metadataCache.getFirstLinkpathDest(
linkText.split("|")[0].split("#")[0],
canvasFile.path
);
if (targetFile != null)
links.add(targetFile.path);
});
});
}
);
markdownFiles.forEach((mdFile) => {
var _a, _b, _c;
if (outFile === null && mdFile.path == outFileName) {
outFile = mdFile;
return;
}
const cache = this.app.metadataCache.getFileCache(mdFile);
for (const ref of [
...(_a = cache.embeds) != null ? _a : [],
...(_b = cache.links) != null ? _b : [],
...(_c = cache.frontmatterLinks) != null ? _c : []
]) {
const txt = this.app.metadataCache.getFirstLinkpathDest(
(0, import_obsidian4.getLinkpath)(ref.link),
mdFile.path
);
if (txt != null)
links.add(txt.path);
}
});
await Promise.all(canvasParsingPromises);
const notLinkedFiles = allFiles.filter(
(file) => this.isFileAnOrphan(file, links, dir)
);
notLinkedFiles.remove(outFile);
let text = "";
let prefix;
if (this.settings.disableWorkingLinks)
prefix = " ";
else
prefix = "";
notLinkedFiles.sort((a, b) => b.stat.size - a.stat.size);
notLinkedFiles.forEach((file) => {
text += prefix + "- [[" + this.app.metadataCache.fileToLinktext(file, "/", false) + "]]\n";
});
Utils.writeAndOpenFile(
this.app,
outFileName,
text,
this.settings.openOutputFile
);
const endTime = Date.now();
const diff = endTime - startTime;
if (diff > 1e3) {
new import_obsidian4.Notice(
`Found ${notLinkedFiles.length} orphaned files in ${diff}ms`
);
}
}
async deleteOrphanedFiles() {
var _a, _b;
if (!await this.app.vault.adapter.exists(
this.settings.outputFileName + ".md"
)) {
new import_obsidian4.Notice(
"Can't find file - Please run the `Find orphaned files' command before"
);
return;
}
const links = (_b = (_a = this.app.metadataCache.getCache(
this.settings.outputFileName + ".md"
)) == null ? void 0 : _a.links) != null ? _b : [];
const filesToDelete = [];
links.forEach((link) => {
const file = this.app.metadataCache.getFirstLinkpathDest(
link.link,
"/"
);
if (!file)
return;
if (this.settings.fileTypesToDelete[0] == "*" || this.settings.fileTypesToDelete.contains(file.extension)) {
filesToDelete.push(file);
}
});
if (filesToDelete.length > 0)
new DeleteFilesModal(this.app, filesToDelete).open();
}
async deleteEmptyFiles() {
var _a, _b;
if (!await this.app.vault.adapter.exists(
this.settings.emptyFilesOutputFileName + ".md"
)) {
new import_obsidian4.Notice(
"Can't find file - Please run the `Find orphaned files' command before"
);
return;
}
const links = (_b = (_a = this.app.metadataCache.getCache(
this.settings.emptyFilesOutputFileName + ".md"
)) == null ? void 0 : _a.links) != null ? _b : [];
const filesToDelete = [];
for (const link of links) {
const file = this.app.metadataCache.getFirstLinkpathDest(
link.link,
"/"
);
if (!file)
return;
filesToDelete.push(file);
}
if (filesToDelete.length > 0)
new DeleteFilesModal(this.app, filesToDelete).open();
}
findBrokenLinks() {
const outFileName = this.settings.unresolvedLinksOutputFileName + ".md";
const links = [];
const brokenLinks = this.app.metadataCache.unresolvedLinks;
for (const sourceFilepath in brokenLinks) {
if (sourceFilepath == this.settings.unresolvedLinksOutputFileName + ".md")
continue;
const fileType = sourceFilepath.substring(
sourceFilepath.lastIndexOf(".") + 1
);
const utils = new Utils(
this.app,
sourceFilepath,
this.settings.unresolvedLinksTagsToIgnore,
this.settings.unresolvedLinksLinksToIgnore,
this.settings.unresolvedLinksDirectoriesToIgnore,
this.settings.unresolvedLinksFilesToIgnore,
this.settings.unresolvedLinksIgnoreDirectories
);
if (utils.shouldIgnoreFile())
continue;
for (const link in brokenLinks[sourceFilepath]) {
const linkFileType = link.substring(link.lastIndexOf(".") + 1);
if (this.settings.unresolvedLinksFileTypesToIgnore.contains(
linkFileType
))
continue;
let formattedFilePath = sourceFilepath;
if (fileType == "md") {
formattedFilePath = sourceFilepath.substring(
0,
sourceFilepath.lastIndexOf(".md")
);
}
const brokenLink = {
files: [formattedFilePath],
link
};
if (links.contains(brokenLink))
continue;
const duplication = links.find((e) => e.link == link);
if (duplication) {
duplication.files.push(formattedFilePath);
} else {
links.push(brokenLink);
}
}
}
Utils.writeAndOpenFile(
this.app,
outFileName,
[
"Don't forget that creating the file from here may create the file in the wrong directory!",
...links.map(
(e) => `- [[${e.link}]] in [[${e.files.join("]], [[")}]]`
)
].join("\n"),
this.settings.openOutputFile
);
}
findFilesWithoutTags() {
const outFileName = this.settings.withoutTagsOutputFileName + ".md";
let outFile;
const files = this.app.vault.getMarkdownFiles();
let withoutFiles = files.filter((file) => {
var _a;
const utils = new Utils(
this.app,
file.path,
[],
[],
this.settings.withoutTagsDirectoriesToIgnore,
this.settings.withoutTagsFilesToIgnore,
true
);
if (utils.shouldIgnoreFile()) {
return false;
}
return ((_a = (0, import_obsidian4.getAllTags)(this.app.metadataCache.getFileCache(file)).length) != null ? _a : 0) <= 0;
});
withoutFiles.remove(outFile);
let prefix;
if (this.settings.disableWorkingLinks)
prefix = " ";
else
prefix = "";
const text = withoutFiles.map((file) => `${prefix}- [[${file.path}]]`).join("\n");
Utils.writeAndOpenFile(
this.app,
outFileName,
text,
this.settings.openOutputFile
);
}
/**
* Checks if the given file in an orphaned file
*
* @param file file to check
* @param links all links in the vault
*/
isFileAnOrphan(file, links, dir) {
if (links.has(file.path))
return false;
if (file.extension == "css")
return false;
if (this.settings.fileTypesToIgnore[0] !== "") {
const containsFileType = this.settings.fileTypesToIgnore.contains(
file.extension
);
if (this.settings.ignoreFileTypes) {
if (containsFileType)
return;
} else {
if (!containsFileType)
return;
}
}
const utils = new Utils(
this.app,
file.path,
this.settings.tagsToIgnore,
this.settings.linksToIgnore,
this.settings.directoriesToIgnore,
this.settings.filesToIgnore,
this.settings.ignoreDirectories,
dir
);
if (utils.shouldIgnoreFile())
return false;
return true;
}
onunload() {
console.log("unloading " + this.manifest.name + " plugin");
}
async loadSettings() {
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
};
/* nosourcemap */

View File

@@ -0,0 +1,10 @@
{
"id": "find-unlinked-files",
"name": "Find orphaned files and broken links",
"version": "1.10.1",
"description": "Find files that are not linked anywhere and would otherwise be lost in your vault. In other words: files with no backlinks.",
"author": "Vinzent",
"fundingUrl": "https://ko-fi.com/vinzent",
"authorUrl": "https://github.com/Vinzent03",
"isDesktopOnly": false
}

View File

@@ -0,0 +1,68 @@
{
"commitMessage": "vault backup: {{date}}",
"autoCommitMessage": "vault backup: {{date}}",
"commitMessageScript": "",
"commitDateFormat": "YYYY-MM-DD HH:mm:ss",
"autoSaveInterval": 30,
"autoPushInterval": 0,
"autoPullInterval": 0,
"autoPullOnBoot": true,
"autoCommitOnlyStaged": false,
"disablePush": false,
"pullBeforePush": true,
"disablePopups": false,
"showErrorNotices": true,
"disablePopupsForNoChanges": false,
"listChangedFilesInMessageBody": false,
"showStatusBar": true,
"updateSubmodules": false,
"syncMethod": "merge",
"mergeStrategy": "none",
"customMessageOnAutoBackup": false,
"autoBackupAfterFileChange": false,
"treeStructure": false,
"refreshSourceControl": true,
"basePath": "",
"differentIntervalCommitAndPush": true,
"changedFilesInStatusBar": false,
"showedMobileNotice": true,
"refreshSourceControlTimer": 7000,
"showBranchStatusBar": true,
"setLastSaveToLastCommit": false,
"submoduleRecurseCheckout": false,
"gitDir": "",
"showFileMenu": true,
"authorInHistoryView": "hide",
"dateInHistoryView": false,
"diffStyle": "split",
"hunks": {
"showSigns": false,
"hunkCommands": false,
"statusBar": "disabled"
},
"lineAuthor": {
"show": false,
"followMovement": "inactive",
"authorDisplay": "initials",
"showCommitHash": false,
"dateTimeFormatOptions": "date",
"dateTimeFormatCustomString": "YYYY-MM-DD HH:mm",
"dateTimeTimezone": "viewer-local",
"coloringMaxAge": "1y",
"colorNew": {
"r": 255,
"g": 150,
"b": 150
},
"colorOld": {
"r": 120,
"g": 160,
"b": 255
},
"textColorCss": "var(--text-muted)",
"ignoreWhitespace": false,
"gutterSpacingFallbackLength": 5,
"lastShownAuthorDisplay": "initials",
"lastShownDateTimeFormatOptions": "date"
}
}

452
.obsidian/plugins/obsidian-git/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"author": "Vinzent",
"authorUrl": "https://github.com/Vinzent03",
"id": "obsidian-git",
"name": "Git",
"description": "Integrate Git version control with automatic backup and other advanced features.",
"isDesktopOnly": false,
"fundingUrl": "https://ko-fi.com/vinzent",
"version": "2.37.1"
}

View File

@@ -0,0 +1,705 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.git-signs-gutter {
.cm-gutterElement {
/* Needed to align the sign properly for different line heigts. Such as
* when having a heading or list item.
*/
padding-top: 0 !important;
}
}
.workspace-leaf-content[data-type="git-view"] .button-border {
border: 2px solid var(--interactive-accent);
border-radius: var(--radius-s);
}
.workspace-leaf-content[data-type="git-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.workspace-leaf-content[data-type="git-history-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.loading {
overflow: hidden;
}
.loading > svg {
animation: 2s linear infinite loading;
transform-origin: 50% 50%;
display: inline-block;
}
.obsidian-git-center {
margin: auto;
text-align: center;
width: 50%;
}
.obsidian-git-textarea {
display: block;
margin-left: auto;
margin-right: auto;
}
.obsidian-git-disabled {
opacity: 0.5;
}
.obsidian-git-center-button {
display: block;
margin: 20px auto;
}
.tooltip.mod-left {
overflow-wrap: break-word;
}
.tooltip.mod-right {
overflow-wrap: break-word;
}
/* Limits the scrollbar to the view body */
.git-view {
display: flex;
flex-direction: column;
position: relative;
height: 100%;
}
.git-tools {
display: flex;
margin-left: auto;
}
.git-tools .type {
padding-left: var(--size-2-1);
display: flex;
align-items: center;
justify-content: center;
width: 11px;
}
.git-tools .type[data-type="M"] {
color: orange;
}
.git-tools .type[data-type="D"] {
color: red;
}
.git-tools .buttons {
display: flex;
}
.git-tools .buttons > * {
padding: 0 0;
height: auto;
}
.workspace-leaf-content[data-type="git-view"] .tree-item-self,
.workspace-leaf-content[data-type="git-history-view"] .tree-item-self {
align-items: center;
}
.workspace-leaf-content[data-type="git-view"]
.tree-item-self:hover
.clickable-icon,
.workspace-leaf-content[data-type="git-history-view"]
.tree-item-self:hover
.clickable-icon {
color: var(--icon-color-hover);
}
/* Highlight an item as active if it's diff is currently opened */
.is-active .git-tools .buttons > * {
color: var(--nav-item-color-active);
}
.git-author {
color: var(--text-accent);
}
.git-date {
color: var(--text-accent);
}
.git-ref {
color: var(--text-accent);
}
/* ====== diff2html ======
The following styles are adapted from the obsidian-version-history plugin by
@kometenstaub https://github.com/kometenstaub/obsidian-version-history-diff/blob/main/src/styles.scss
which itself is adapted from the diff2html library with the following original license:
https://github.com/rtfpessoa/diff2html/blob/master/LICENSE.md
Copyright 2014-2016 Rodrigo Fernandes https://rtfpessoa.github.io/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.theme-dark,
.theme-light {
--git-delete-bg: #ff475040;
--git-delete-hl: #96050a75;
--git-insert-bg: #68d36840;
--git-insert-hl: #23c02350;
--git-change-bg: #ffd55840;
--git-selected: #3572b0;
--git-delete: #c33;
--git-insert: #399839;
--git-change: #d0b44c;
--git-move: #3572b0;
}
.git-diff {
.d2h-d-none {
display: none;
}
.d2h-wrapper {
text-align: left;
border-radius: 0.25em;
overflow: auto;
}
.d2h-file-header.d2h-file-header {
background-color: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
font-family:
Source Sans Pro,
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
height: 35px;
padding: 5px 10px;
}
.d2h-file-header,
.d2h-file-stats {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.d2h-file-header {
display: none;
}
.d2h-file-stats {
font-size: 14px;
margin-left: auto;
}
.d2h-lines-added {
border: 1px solid var(--color-green);
border-radius: 5px 0 0 5px;
color: var(--color-green);
padding: 2px;
text-align: right;
vertical-align: middle;
}
.d2h-lines-deleted {
border: 1px solid var(--color-red);
border-radius: 0 5px 5px 0;
color: var(--color-red);
margin-left: 1px;
padding: 2px;
text-align: left;
vertical-align: middle;
}
.d2h-file-name-wrapper {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 15px;
width: 100%;
}
.d2h-file-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-normal);
font-size: var(--h5-size);
}
.d2h-file-wrapper {
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
margin-bottom: 1em;
max-height: 100%;
}
.d2h-file-collapse {
-webkit-box-pack: end;
-ms-flex-pack: end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
cursor: pointer;
display: none;
font-size: 12px;
justify-content: flex-end;
padding: 4px 8px;
}
.d2h-file-collapse.d2h-selected {
background-color: var(--git-selected);
}
.d2h-file-collapse-input {
margin: 0 4px 0 0;
}
.d2h-diff-table {
border-collapse: collapse;
font-family: var(--font-monospace);
font-size: var(--code-size);
width: 100%;
}
.d2h-files-diff {
width: 100%;
}
.d2h-file-diff {
/*
overflow-y: scroll;
*/
border-radius: 5px;
font-size: var(--font-text-size);
line-height: var(--line-height-normal);
}
.d2h-file-side-diff {
display: inline-block;
margin-bottom: -8px;
margin-right: -4px;
overflow-x: scroll;
overflow-y: hidden;
width: 50%;
}
.d2h-code-line {
padding-left: 6em;
padding-right: 1.5em;
}
.d2h-code-line,
.d2h-code-side-line {
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 100%;
}
.d2h-code-side-line {
/* needed to be changed */
padding-left: 0.5em;
padding-right: 0.5em;
}
.d2h-code-line-ctn {
word-wrap: normal;
background: none;
display: inline-block;
padding: 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
vertical-align: middle;
width: 100%;
/* only works for line-by-line */
white-space: pre-wrap;
}
.d2h-code-line del,
.d2h-code-side-line del {
background-color: var(--git-delete-hl);
color: var(--text-normal);
}
.d2h-code-line del,
.d2h-code-line ins,
.d2h-code-side-line del,
.d2h-code-side-line ins {
border-radius: 0.2em;
display: inline-block;
margin-top: -1px;
text-decoration: none;
vertical-align: middle;
}
.d2h-code-line ins,
.d2h-code-side-line ins {
background-color: var(--git-insert-hl);
text-align: left;
}
.d2h-code-line-prefix {
word-wrap: normal;
background: none;
display: inline;
padding: 0;
white-space: pre;
}
.line-num1 {
float: left;
}
.line-num1,
.line-num2 {
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
/*
padding: 0 0.5em;
*/
text-overflow: ellipsis;
width: 2.5em;
padding-left: 0;
}
.line-num2 {
float: right;
}
.d2h-code-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
display: inline-block;
position: absolute;
text-align: right;
width: 5.5em;
}
.d2h-code-linenumber:after {
content: "\200b";
}
.d2h-code-side-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
overflow: hidden;
padding: 0 0.5em;
text-align: right;
text-overflow: ellipsis;
width: 4em;
/* needed to be changed */
display: table-cell;
position: relative;
}
.d2h-code-side-linenumber:after {
content: "\200b";
}
.d2h-code-side-emptyplaceholder,
.d2h-emptyplaceholder {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
}
.d2h-code-line-prefix,
.d2h-code-linenumber,
.d2h-code-side-linenumber,
.d2h-emptyplaceholder {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.d2h-code-linenumber,
.d2h-code-side-linenumber {
direction: rtl;
}
.d2h-del {
background-color: var(--git-delete-bg);
border-color: var(--git-delete-hl);
}
.d2h-ins {
background-color: var(--git-insert-bg);
border-color: var(--git-insert-hl);
}
.d2h-info {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
color: var(--text-faint);
}
.d2h-del,
.d2h-ins,
.d2h-file-diff .d2h-change {
color: var(--text-normal);
}
.d2h-file-diff .d2h-del.d2h-change {
background-color: var(--git-change-bg);
}
.d2h-file-diff .d2h-ins.d2h-change {
background-color: var(--git-insert-bg);
}
.d2h-file-list-wrapper {
a {
text-decoration: none;
cursor: default;
-webkit-user-drag: none;
}
svg {
display: none;
}
}
.d2h-file-list-header {
text-align: left;
}
.d2h-file-list-title {
display: none;
}
.d2h-file-list-line {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-align: left;
}
.d2h-file-list {
}
.d2h-file-list > li {
border-bottom: 1px solid var(--background-modifier-border);
margin: 0;
padding: 5px 10px;
}
.d2h-file-list > li:last-child {
border-bottom: none;
}
.d2h-file-switch {
cursor: pointer;
display: none;
font-size: 10px;
}
.d2h-icon {
fill: currentColor;
margin-right: 10px;
vertical-align: middle;
}
.d2h-deleted {
color: var(--git-delete);
}
.d2h-added {
color: var(--git-insert);
}
.d2h-changed {
color: var(--git-change);
}
.d2h-moved {
color: var(--git-move);
}
.d2h-tag {
background-color: var(--background-secondary);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 10px;
margin-left: 5px;
padding: 0 2px;
}
.d2h-deleted-tag {
border: 1px solid var(--git-delete);
}
.d2h-added-tag {
border: 1px solid var(--git-insert);
}
.d2h-changed-tag {
border: 1px solid var(--git-change);
}
.d2h-moved-tag {
border: 1px solid var(--git-move);
}
/* needed for line-by-line*/
.d2h-diff-tbody {
position: relative;
}
}
/* ====================== Line Authoring Information ====================== */
.cm-gutterElement.obs-git-blame-gutter {
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
border-width: 0px 2px 0.2px 2px;
border-style: solid;
border-color: var(--background-secondary);
background-color: var(--background-secondary);
}
.cm-gutterElement.obs-git-blame-gutter > div,
.line-author-settings-preview {
/* delegate text color to settings */
color: var(--obs-git-gutter-text);
font-family: monospace;
height: 100%; /* ensure, that age-based background color occupies entire parent */
text-align: right;
padding: 0px 6px 0px 6px;
white-space: pre; /* Keep spaces and do not collapse them. */
}
@media (max-width: 800px) {
/* hide git blame gutter not to superpose text */
.cm-gutterElement.obs-git-blame-gutter {
display: none;
}
}
.git-unified-diff-view,
.git-split-diff-view .cm-deletedLine .cm-changedText {
background-color: #ee443330;
}
.git-unified-diff-view,
.git-split-diff-view .cm-insertedLine .cm-changedText {
background-color: #22bb2230;
}
.git-obscure-prompt[git-is-obscured="true"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg>');
}
.git-obscure-prompt[git-is-obscured="false"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"></path><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"></path><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"></path><path d="m2 2 20 20"></path></svg>');
}
/* Override styling of Codemirror merge view "collapsed lines" indicator */
.git-split-diff-view .ͼ2 .cm-collapsedLines {
background: var(--interactive-normal);
border-radius: var(--radius-m);
color: var(--text-accent);
font-size: var(--font-small);
padding: var(--size-4-1) var(--size-4-1);
}
.git-split-diff-view .ͼ2 .cm-collapsedLines:hover {
background: var(--interactive-hover);
color: var(--text-accent-hover);
}
.git-signs-gutter {
.cm-gutterElement {
display: grid;
}
}
.git-gutter-marker:hover {
border-radius: 2px;
}
.git-gutter-marker.git-add {
background-color: var(--color-green);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-change {
background-color: var(--color-yellow);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-changedelete {
color: var(--color-yellow);
font-weight: var(--font-bold);
font-size: 1rem;
justify-self: center;
height: inherit;
}
.git-gutter-marker.git-delete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: end;
}
.git-gutter-marker.git-topdelete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: start;
}
div:hover > .git-gutter-marker.git-change {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-add {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-delete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-topdelete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-changedelete {
font-weight: var(--font-bold);
}
.git-gutter-marker.staged {
opacity: 0.5;
}
.git-diff {
.cm-merge-revert {
width: 4em;
}
/* Ensure that merge revert markers are positioned correctly */
.cm-merge-revert > * {
position: absolute;
background-color: var(--background-secondary);
display: flex;
}
}
/* Prevent shifting of the editor when git signs gutter is the only gutter present */
.cm-gutters.cm-gutters-before:has(> .git-signs-gutter:only-child) {
margin-inline-end: 0;
.git-signs-gutter {
margin-inline-start: -1rem;
}
}
.git-changes-status-bar-colored {
.git-add {
color: var(--color-green);
}
.git-change {
color: var(--color-yellow);
}
.git-delete {
color: var(--color-red);
}
}
.git-changes-status-bar .git-add {
margin-right: 0.3em;
}
.git-changes-status-bar .git-change {
margin-right: 0.3em;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"id": "obsidian-importer",
"name": "Importer",
"version": "1.8.4",
"minAppVersion": "0.15.0",
"description": "Import data from Notion, Evernote, Apple Notes, Microsoft OneNote, Google Keep, Bear, Roam, Textbundle, CSV, and HTML files.",
"author": "Obsidian",
"authorUrl": "https://obsidian.md",
"isDesktopOnly": false
}

View File

@@ -0,0 +1,173 @@
.modal.mod-importer {
max-height: var(--modal-height);
padding: var(--size-4-4) 0 0 0;
position: relative;
overflow: hidden;
}
.modal.mod-importer .modal-title {
padding: 0 var(--size-4-4);
}
.modal.mod-importer .modal-content {
overflow: auto;
padding: var(--size-4-4);
margin-bottom: calc(var(--input-height) + var(--size-4-8));
border-top: var(--border-width) solid var(--background-modifier-border);
}
.modal.mod-importer .modal-button-container {
margin: 0 0 0 calc(var(--size-4-4) * -1);
padding: var(--size-4-4);
gap: var(--size-4-2);
position: absolute;
bottom: 0;
background-color: var(--background-primary);
border-top: var(--border-width) solid var(--background-modifier-border);
width: 100%;
}
.importer-progress-bar {
width: 100%;
height: 8px;
background-color: var(--background-secondary);
overflow: hidden;
box-shadow: inset 0px 0px 0px 1px var(--background-modifier-border);
border-radius: var(--radius-s);
}
.importer-progress-bar-inner {
width: 0;
height: 100%;
background-color: var(--interactive-accent);
}
.importer-status {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: var(--size-4-2) 0;
}
.importer-stats-container {
display: flex;
justify-content: space-evenly;
margin-top: var(--size-4-5);
margin-bottom: var(--size-4-5);
}
.importer-stat {
text-align: center;
}
.importer-stat-count {
font-size: var(--font-ui-large);
}
.importer-log {
overflow: auto;
flex-grow: 1;
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
color: var(--text-muted);
border: 1px solid var(--background-modifier-border);
padding: var(--size-4-4);
background-color: var(--background-secondary);
border-radius: var(--radius-s);
max-height: 300px;
user-select: text;
}
.importer-log .list-item {
display: inline-block;
line-height: var(--line-height-normal);
white-space: pre;
margin: var(--size-2-1);
}
.importer-error {
color: var(--text-error);
}
/* Template configuration styles */
.importer-frontmatter-header {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.importer-frontmatter-header h4 {
margin: 0;
}
.importer-select-all-setting {
padding: 0;
border: none;
}
.importer-select-all-setting .setting-item-info {
padding-inline-end: var(--size-4-2);
}
.importer-column-list {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
padding: var(--size-4-3) 0;
}
.importer-column-header-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
font-size: var(--font-ui-smaller);
color: var(--text-muted);
padding: var(--size-2-1) 0;
}
.importer-column-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
background-color: var(--background-primary);
border-radius: var(--radius-s);
}
.importer-column-name-col {
flex: 0 0 150px;
min-width: 0;
}
.importer-column-value-col {
flex: 0 0 200px;
min-width: 0;
}
.importer-column-property {
width: 100%;
}
.importer-column-example-col {
flex: 1;
min-width: 0;
font-size: var(--font-ui-smaller);
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: var(--size-2-1) var(--size-4-1);
}
.importer-column-delete-col {
flex-shrink: 0;
width: 32px;
display: flex;
align-items: center;
justify-content: center;
}
/* Fixed width buttons to prevent resizing during loading */
.notion-load-button {
width: 70px;
}
.notion-toggle-button {
width: 95px;
}

View File

@@ -0,0 +1,319 @@
{
"ruleConfigs": {
"add-blank-line-after-yaml": {
"enabled": false
},
"dedupe-yaml-array-values": {
"enabled": false,
"dedupe-alias-key": true,
"dedupe-tag-key": true,
"dedupe-array-keys": true,
"ignore-keys": ""
},
"escape-yaml-special-characters": {
"enabled": false,
"try-to-escape-single-line-arrays": false
},
"force-yaml-escape": {
"enabled": false,
"force-yaml-escape-keys": ""
},
"format-tags-in-yaml": {
"enabled": false
},
"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": true,
"text-to-insert": "title: \ndescription: \ntags: \ndate: \nlastmod: \ntype: \ncategory: \nstatus: "
},
"move-tags-to-yaml": {
"enabled": false,
"how-to-handle-existing-tags": "Nothing",
"tags-to-ignore": ""
},
"remove-yaml-keys": {
"enabled": false,
"yaml-keys-to-remove": ""
},
"sort-yaml-array-values": {
"enabled": false,
"sort-alias-key": true,
"sort-tag-key": true,
"sort-array-keys": true,
"ignore-keys": "",
"sort-order": "Ascending Alphabetical"
},
"yaml-key-sort": {
"enabled": true,
"yaml-key-priority-sort-order": "",
"priority-keys-at-start-of-yaml": true,
"yaml-sort-order-for-other-keys": "None"
},
"yaml-timestamp": {
"enabled": true,
"date-created": true,
"date-created-key": "date",
"date-created-source-of-truth": "file system",
"date-modified": true,
"date-modified-key": "lastmod",
"date-modified-source-of-truth": "file system",
"format": "YYYY-MM-DD HH:mm",
"convert-to-utc": false,
"update-on-file-contents-updated": "never"
},
"yaml-title": {
"enabled": true,
"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, inasmuch, even, whether, whose, whoever, why, how, whatever, what, both, and, or, either, neither, nor, just, rather, 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": false,
"style": "space"
},
"convert-bullet-list-markers": {
"enabled": true
},
"default-language-for-code-fences": {
"enabled": false,
"default-language": ""
},
"emphasis-style": {
"enabled": false,
"style": "consistent"
},
"no-bare-urls": {
"enabled": false,
"no-bare-uris": false
},
"ordered-list-style": {
"enabled": false,
"number-style": "ascending",
"list-end-style": "."
},
"proper-ellipsis": {
"enabled": false
},
"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": false
},
"remove-hyphenated-line-breaks": {
"enabled": false
},
"remove-multiple-spaces": {
"enabled": false
},
"strong-style": {
"enabled": false,
"style": "consistent"
},
"two-spaces-between-lines-with-content": {
"enabled": false,
"line-break-indicator": " "
},
"unordered-list-style": {
"enabled": false,
"list-style": "consistent"
},
"compact-yaml": {
"enabled": false,
"inner-new-lines": false
},
"consecutive-blank-lines": {
"enabled": false
},
"convert-spaces-to-tabs": {
"enabled": false,
"tabsize": 4
},
"empty-line-around-blockquotes": {
"enabled": false
},
"empty-line-around-code-fences": {
"enabled": false
},
"empty-line-around-horizontal-rules": {
"enabled": false
},
"empty-line-around-math-blocks": {
"enabled": false
},
"empty-line-around-tables": {
"enabled": false
},
"heading-blank-lines": {
"enabled": true,
"bottom": true,
"empty-line-after-yaml": true
},
"line-break-at-document-end": {
"enabled": false
},
"move-math-block-indicators-to-their-own-line": {
"enabled": false
},
"paragraph-blank-lines": {
"enabled": false
},
"remove-empty-lines-between-list-markers-and-checklists": {
"enabled": false
},
"remove-link-spacing": {
"enabled": false
},
"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": false
},
"space-between-chinese-japanese-or-korean-and-english-or-numbers": {
"enabled": false,
"english-symbols-punctuation-before": "-+;:'\"°%$)]",
"english-symbols-punctuation-after": "-+'\"([¥$"
},
"trailing-spaces": {
"enabled": false,
"two-space-line-break": false
},
"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
}
},
"lintOnSave": true,
"recordLintOnSaveLogs": false,
"displayChanged": true,
"suppressMessageWhenNoChange": false,
"lintOnFileChange": false,
"displayLintOnFileChangeNotice": false,
"settingsConvertedToConfigKeyValues": true,
"foldersToIgnore": [],
"filesToIgnore": [],
"linterLocale": "system-default",
"logLevel": "ERROR",
"lintCommands": [],
"customRegexes": [
{
"name": "Convertir Wikilinks en Markdown",
"regex": "\\[\\[([^|\\]]+)\\|?([^\\]]*)\\]\\]",
"replacement": "[$2]($1)",
"flags": "g",
"description": "Transforme [[Lien|Texte]] en [Texte](Lien) pour la compatibilité web.",
"enabled": true
},
{
"name": "Nettoyer espaces insécables",
"regex": "\\xA0",
"replacement": " ",
"flags": "g",
"description": "Remplace les espaces invisibles qui cassent le HTML.",
"enabled": true
},
{
"name": "Langage par défaut blocs de code",
"regex": "^(\\s*)(\\`{3,})[\\s\\n]",
"replacement": "$1$2text\n",
"flags": "gm",
"description": "Ajoute 'text' aux blocs de code vides pour éviter les erreurs de rendu.",
"enabled": true
}
],
"commonStyles": {
"aliasArrayStyle": "single-line",
"tagArrayStyle": "single-line",
"minimumNumberOfDollarSignsToBeAMathBlock": 2,
"escapeCharacter": "\"",
"removeUnnecessaryEscapeCharsForMultiLineArrays": false
}
}

File diff suppressed because one or more lines are too long

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
}

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}

File diff suppressed because one or more lines are too long

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
}

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;
}

5
.obsidian/templates.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"dateFormat": "YYYYMMDD",
"timeFormat": "HHmmss",
"folder": "references/modeles"
}

View File

@@ -0,0 +1,8 @@
{
"name": "Minimal",
"version": "8.1.5",
"minAppVersion": "1.9.0",
"author": "@kepano",
"authorUrl": "https://twitter.com/kepano",
"fundingUrl": "https://www.buymeacoffee.com/kepano"
}

2251
.obsidian/themes/Minimal/theme.css vendored Normal file

File diff suppressed because one or more lines are too long

7
.obsidian/themes/PLN/manifest.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"name": "PLN",
"version": "1.18.0",
"minAppVersion": "1.7.7",
"author": "PipeItToDevNull",
"authorUrl": "https://docs.dev0.sh"
}

2584
.obsidian/themes/PLN/theme.css vendored Normal file

File diff suppressed because it is too large Load Diff

19
.obsidian/types.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"types": {
"aliases": "aliases",
"cssclasses": "multitext",
"tags": "tags",
"article_etat": "multitext",
"catgeorie": "multitext",
"date create": "date",
"date_create": "date",
"page_type": "multitext",
"draft": "checkbox",
"type": "multitext",
"date": "datetime",
"date_created": "datetime",
"lastmod": "datetime",
"category": "multitext",
"status": "text"
}
}

View File

@@ -1,151 +0,0 @@
---
title: publier des notes Git sur un site
description: Utiliser Git comme "source de vérité" pour des notes permet de bénéficier du versioning tout en gardant une totale liberté sur l'apparence finale.
type:
- article
tags: [git, ssg]
category:
- "[[Guide]]"
date: 2026-02-21 14:22
lastmod: 2026-02-21 14:51
status: brouillon
---
objectifs :
écrire en local des notes, guides, tuto > transformer les données en site web (publier en même temps)
utilisation d'un dépôt centralisé, pour sauvegarder les notes mais également faire un travail collaboratif, sur plusieurs machines, voir plusieurs personnes.
détail :
Ecrire ces notes avec l'application Obisidian, logiciel de gestion des connaissances personnelles et un logiciel de prise de notes qui fonctionne à partir de fichiers Markdown. (détailler les avantages du Markdown et ces inconvénient) (détailler les avantage d'obsisdian et ces inconvénients)
Utilisation du logiciel hugo comme un générateur de sites statiques (SSG) . peut etre paler d'un theme qui permet de gérer le digital garden.
difficultés :
il y a des parties du site qui sont dynamiques (php) et ne peut pas etre géré par obsidian, ni hugo.
Expliquer comment faire avec Theia par exemple ou autre. Peut etre externaliser les parties dynamqiues (les mettre sur un autre site).
---
Voici un guide complet pour transformer votre prise de notes locale en un écosystème de publication web robuste et collaboratif.
---
## Transformer ses notes Obsidian en "Digital Garden" : Le Guide Complet
Lidée est simple mais puissante : utiliser **Obsidian** pour lécriture, **Git** pour la collaboration, et **Hugo** pour transformer vos fichiers Markdown en un site web ultra-rapide. Voici comment bâtir ce flux de travail.
---
## 1. L'Art de l'écriture : Pourquoi Obsidian et Markdown ?
Le cœur de votre système repose sur des fichiers texte brut. Contrairement aux formats propriétaires (comme .docx), le **Markdown** garantit la pérennité de vos données.
### Le Markdown : La simplicité au service de la structure
- **Avantages :** * **Portabilité :** Lisible par n'importe quel éditeur de texte.
- **Léger :** Pas de mise en forme cachée qui alourdit le fichier.
- **Rapidité :** On formate pendant qu'on écrit (gras, titres, listes) sans lâcher le clavier.
- **Inconvénients :** * **Courbe d'apprentissage :** Il faut mémoriser quelques symboles (`#`, `**`, `[]`).
- **Rendu visuel :** Nécessite une prévisualisation pour voir le résultat final.
### Obsidian : Votre second cerveau
Obsidian n'est pas qu'un éditeur, c'est une interface au-dessus de vos dossiers de fichiers.
- **Avantages :** * **Liens bidirectionnels :** Créez des connexions entre vos notes (le fameux "Graph View").
- **Plugins :** Une communauté immense (ex: _Dataview_ pour requêter vos notes).
- **Local-first :** Vos données restent sur votre disque dur.
- **Inconvénients :** * **Synchronisation native payante :** (Bien que contournable via Git, comme nous allons le voir).
- **Complexité :** On peut vite passer plus de temps à configurer l'outil qu'à écrire.
---
## 2. Centralisation et Collaboration : Le rôle de Git
Pour travailler sur plusieurs machines ou à plusieurs, le "dépôt centralisé" (GitHub, GitLab ou Gitea) est indispensable.
- **Versionnage :** Chaque modification est enregistrée. Si vous faites une erreur, vous pouvez revenir en arrière.
- **Collaboration :** Plusieurs personnes peuvent travailler sur des notes différentes. Les "conflits" de modification sont gérés intelligemment.
- **Automatisation :** Dès que vous "poussez" (push) vos notes vers le dépôt, le site web peut se mettre à jour tout seul.
---
## 3. Publication : Hugo et le concept de Digital Garden
**Hugo** est un générateur de sites statiques (SSG). Il prend vos fichiers Markdown et les transforme en pages HTML en quelques millisecondes.
### Le thème "Digital Garden"
Pour Obsidian, il est recommandé d'utiliser un thème Hugo spécifique, comme **Hugo Obsidian** ou **Quartz**. Ces thèmes permettent de :
- Gérer les liens internes de type `[[Note]]`.
- Afficher un graphique de vos notes sur le web.
- Permettre une navigation non-linéaire (exploration libre pour vos lecteurs).
---
## 4. Le défi du Dynamique (PHP)
C'est ici que les choses se corsent. Hugo génère des fichiers **statiques** (HTML/CSS/JS). Par définition, il ne peut pas exécuter de code serveur comme le **PHP**.
### Pourquoi Obsidian et Hugo ne suffisent pas ?
Obsidian est un éditeur de texte, pas un environnement de développement web complet. Si vous avez besoin d'un formulaire de contact complexe, d'un espace membre ou d'un outil de calcul dynamique en PHP, Hugo ne pourra pas le "compiler".
### Solution 1 : L'environnement hybride avec Theia
**Theia** (ou VS Code Server) est un IDE accessible via navigateur.
- Vous pouvez l'installer sur votre serveur pour éditer directement les scripts PHP qui ne sont pas dans votre "jardin de notes".
- Il permet de garder la main sur le code "vivant" là où Obsidian gère le contenu "froid".
### Solution 2 : L'externalisation (Recommandé)
Plutôt que d'essayer de forcer du PHP dans un site statique, séparez les responsabilités :
1. **Le Jardin (Hugo) :** Vos guides, tutos et notes sur `notes.votresite.com`.
2. **L'App (PHP) :** Vos outils dynamiques sur `app.votresite.com`.
3. **L'intégration :** Utilisez des **iFrames** ou des appels **API (JavaScript)** pour afficher des données dynamiques dans vos pages Hugo.
> **Note :** Si votre besoin dynamique est simple (commentaires, recherche), il existe des alternatives "statiques" comme _Cusdis_ pour les commentaires ou _Pagefind_ pour la recherche.
---
## Résumé du Workflow
1. **Écriture :** Vous rédigez dans Obsidian sur votre PC.
2. **Synchronisation :** Vous envoyez vos modifications sur GitHub.
3. **Déploiement :** Un service (comme Netlify ou Vercel) détecte le changement, lance **Hugo**, et publie le site.
4. **Dynamique :** Vos scripts PHP sont hébergés à part et appelés via des liens ou des intégrations légères.
---
Souhaitez-vous que je vous aide à rédiger le fichier de configuration YAML pour connecter votre dépôt Obsidian à un déploiement automatique sur le web ?

View File

@@ -0,0 +1,87 @@
---
title: 'Bâtir son "Jardin Numérique" : de la prise de notes locale à la publication web collaborative'
description: Contrairement à un blog classique où les articles meurent dans les archives, un jardin numérique est une base de connaissance vivante, interconnectée et évolutive.
type:
- article
tags: [git, ssg, digital-garden]
category:
- "[[Guide]]"
date: 2026-02-21 14:22
lastmod: 2026-02-21 15:57
status: brouillon
---
# Bâtir son "Jardin Numérique" : de la prise de notes locale à la publication web collaborative
Lapproche que je développe ici nest pas nouvelle pour moi ; **elle constitue le fil rouge de mon organisation personnelle depuis mes études universitaires.** Dans un monde où linformation sature nos écrans, jaffine depuis des années cette stratégie : transformer des notes locales en un site web vivant et automatisé. L'objectif reste inchangé depuis mes débuts : bâtir un système collaboratif et durable pour fixer la connaissance plutôt que de la laisser s'évaporer.
## 1. La fondation : le Markdown et le "Local-First"
Aujourd'hui, le cœur de ce système repose sur un choix technique crucial : le **Markdown**. Plutôt que d'utiliser des formats propriétaires (comme le .docx), j'utilise du texte brut enrichi de balises simples.
### Pourquoi le Markdown ?
- **Indépendance :** vos notes ne dépendent d'aucun logiciel spécifique. Si un outil disparaît, vos fichiers restent lisibles par n'importe quel ordinateur.
- **Légèreté :** des milliers de pages de notes occupent moins de place qu'une seule photo haute définition.
- **Standardisation :** c'est le langage universel du web et des développeurs.
> **Le bémol :** le Markdown n'est pas un outil de mise en page "artistique". C'est un format structurel. Si l'on cherche à faire du graphisme complexe sur chaque page, ce n'est pas l'outil idéal.
---
## 2. L'architecte : Obsidian
Pour gérer ces fichiers Markdown, **Obsidian** s'impose comme l'outil de référence. Contrairement à une application de notes classique, il fonctionne comme un "deuxième cerveau".
### Les points forts
- **Liens bidirectionnels :** on peut relier une note à une autre (comme sur Wikipédia), créant ainsi une toile de connaissances interconnectées.
- **Maîtrise des données :** tout est stocké en local sur votre machine. Aucun cloud n'est imposé.
- **Évolutivité :** grâce à ses nombreux plugins, Obsidian peut devenir un gestionnaire de tâches, une base de données ou un véritable outil de publication.
### Les points faibles
- Il nécessite une petite phase d'apprentissage pour exploiter pleinement la puissance des liens.
- La synchronisation entre plusieurs appareils demande une configuration spécifique (via Git ou un service tiers).
---
## 3. La vitrine : Hugo et le déploiement automatique
Une fois les notes rédigées, comment les transformer en un site web élégant et rapide ? C'est là qu'intervient **Hugo**, un générateur de sites statiques (SSG).
L'idée est d'utiliser un thème spécifique au "Digital Garden" (comme _Quartz_ ou _Hugo-Obsidian_). Ce thème va lire vos notes Obsidian et recréer automatiquement la navigation, les liens entre les pages et même le graphique visuel de vos idées sur le web.
### Le flux de travail collaboratif
En utilisant un dépôt centralisé (comme **GitHub**), vous permettez à plusieurs personnes de travailler simultanément sur les mêmes guides :
1. **Rédaction** sur votre ordinateur (en local).
2. **Sauvegarde** (Push) vers le dépôt centralisé.
3. **Publication instantanée :** le site web se met à jour automatiquement dès qu'une modification est validée.
---
## 4. Le défi du dynamisme
L'une des limites de cette approche "statique" est l'impossibilité de gérer nativement des fonctions dynamiques (formulaires complexes, bases de données en temps réel, scripts PHP, etc.).
### Comment contourner cette difficulté ?
L'astuce consiste à adopter une **approche hybride** :
- **Externalisation :** gardez votre documentation et vos guides sur la partie statique (Hugo) pour la performance, et hébergez vos outils dynamiques sur un environnement séparé (un serveur PHP classique ou une instance **Theia/VS Code Server**).
- **Intégration fluide :** liez les deux univers par des menus communs ou des intégrations (iframes, API). Cela permet de profiter de la robustesse d'un site statique tout en conservant la puissance d'outils de gestion de données interactifs.

View File

@@ -7,7 +7,7 @@ type:
category:
- "[[Administratif et légal]]"
status: terminé
lastmod: 2026-02-21 12:21
lastmod: 2026-02-21 15:28
date: 2026-02-20 20:48
---
@@ -21,7 +21,7 @@ Si vous avez des questions sur un tutoriel, une remarque sur la documentation ou
### Formulaire de contact
Le moyen le plus simple est d'utiliser mon interface de contact dédiée :
[👉 Accéder au formulaire de contact](https://www.abonnel.fr/contact)
[👉 Accéder au formulaire de contact](https://outils.a5l.fr/contact)
### Réseaux et Veille

View File

@@ -5,13 +5,15 @@ description: Wiki personnel de Cédrix regroupant documentation technique, guide
category:
status: terminé
tags: [accueil, index, wiki, documentation, Linux, open-source, domotique]
lastmod: 2026-02-21 15:24
lastmod: 2026-02-21 15:44
date: 2026-02-19 04:31
---
Un [digital garden](digital%20garden.md) consacré à la documentation technique : **Linux**, technologies **Open Source**, **domotique** et systèmes numériques.
Contrairement à un blog figé, ce site regroupe des notes vivantes, des guides en cours de rédaction et des procédures techniques que j'utilise au quotidien. C'est ici que je centralise la marque **S'informer sur la tech**.
-- *[Cédrix](Cédrix.md)*
---
## 📚 Explorer les notes
@@ -27,6 +29,11 @@ Contrairement à un blog figé, ce site regroupe des notes vivantes, des guides
*Contenus multimédias.*
> [!danger] Etat des services
> **11 décembre 2025**
> mindcast.fr est actuellement hors ligne suite à une panne matérielle.
> Reconstruction prévue sur une nouvelle infrastructure.
- [Podcast — Sinformer sur la tech](https://mindcast.fr/@sinformersurlatech)
- [Vidéos — Sinformer sur la tech](https://www.youtube.com/@SInformerSurLaTech)
@@ -37,9 +44,3 @@ Contrairement à un blog figé, ce site regroupe des notes vivantes, des guides
- [[legal-notices|Informations légales]]
- [[contact|Contact]]
---
> [!danger] Etat des services
> **11 décembre 2025**
> mindcast.fr est actuellement hors ligne suite à une panne matérielle.
> Reconstruction prévue sur une nouvelle infrastructure.