vault backup: 2026-06-09 14:45:18

This commit is contained in:
Louis 2026-06-09 14:45:18 +02:00
parent c76d7a4991
commit 75cb7862ea
No known key found for this signature in database
138 changed files with 409129 additions and 0 deletions

22
.luarc.json Normal file
View file

@ -0,0 +1,22 @@
{
"Generator": [
"Quarto",
"This file provides type information for Lua completion and diagnostics.",
"Quarto will automatically update this file to reflect the current path",
"of your Quarto installation, and the file will also be added to .gitignore",
"since it points to the absolute path of Quarto on the local system.",
"Remove the 'Generator' key to manage this file's contents manually."
],
"Lua.runtime.version": "Lua 5.3",
"Lua.workspace.checkThirdParty": false,
"Lua.workspace.library": [
"/opt/quarto/share/lua-types"
],
"Lua.runtime.plugin": "/opt/quarto/share/lua-plugin/plugin.lua",
"Lua.completion.showWord": "Disable",
"Lua.completion.keywordSnippet": "Both",
"Lua.diagnostics.disable": [
"lowercase-global",
"trailing-space"
]
}

1
.obsidian/app.json vendored Normal file
View file

@ -0,0 +1 @@
{}

1
.obsidian/appearance.json vendored Normal file
View file

@ -0,0 +1 @@
{}

3
.obsidian/backlink.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"backlinkInDocument": false
}

19
.obsidian/community-plugins.json vendored Normal file
View file

@ -0,0 +1,19 @@
[
"obsidian-livesync",
"obsidian-latex-suite",
"qmd-as-md-obsidian",
"obsidian-zotero-desktop-connector",
"pandoc-extended-markdown",
"obsidian-pandoc-reference-list",
"obsidian-linter",
"heading-level-indent",
"obsidian-citation-plugin",
"dataview",
"obsidian-custom-file-extensions-plugin",
"editing-toolbar",
"obsidian-tasks-plugin",
"pseudocode-in-obs",
"obsidian-tikzjax",
"obsidian-git",
"templater-obsidian"
]

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": 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": false,
"file-recovery": true,
"publish": false,
"sync": false,
"bases": true,
"webviewer": false
}

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": 0.6666666666666666,
"close": true
}

3
.obsidian/page-preview.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"preview": 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,535 @@
{
"lastVersion": "4.0.8",
"aestheticStyle": "default",
"positionStyle": "top",
"menuCommands": [
{
"id": "editing-toolbar:editor-undo",
"name": "Undo Edit",
"icon": "undo-glyph"
},
{
"id": "editing-toolbar:editor-redo",
"name": "Redo Edit",
"icon": "redo-glyph"
},
{
"id": "editing-toolbar:toggle-format-brush",
"name": "Format Brush",
"icon": "paintbrush"
},
{
"id": "editing-toolbar:format-eraser",
"name": "Clear Text Formatting",
"icon": "eraser"
},
{
"id": "editing-toolbar:header2-text",
"name": "Header 2",
"icon": "header-2"
},
{
"id": "editing-toolbar:header3-text",
"name": "Header 3",
"icon": "header-3"
},
{
"id": "SubmenuCommands-header",
"name": "submenu",
"icon": "header-n",
"SubmenuCommands": [
{
"id": "editing-toolbar:header1-text",
"name": "Header 1",
"icon": "header-1"
},
{
"id": "editing-toolbar:header4-text",
"name": "Header 4",
"icon": "header-4"
},
{
"id": "editing-toolbar:header5-text",
"name": "Header 5",
"icon": "header-5"
},
{
"id": "editing-toolbar:header6-text",
"name": "Header 6",
"icon": "header-6"
}
]
},
{
"id": "editing-toolbar:toggle-bold",
"name": "Bold",
"icon": "bold-glyph"
},
{
"id": "editing-toolbar:toggle-italics",
"name": "Italic",
"icon": "italic-glyph"
},
{
"id": "editing-toolbar:toggle-strikethrough",
"name": "Strikethrough",
"icon": "strikethrough-glyph"
},
{
"id": "editing-toolbar:underline",
"name": "Underline",
"icon": "underline-glyph"
},
{
"id": "editing-toolbar:toggle-highlight",
"name": "Highlight",
"icon": "highlight-glyph"
},
{
"id": "SubmenuCommands-text-tools",
"name": "Text Tools",
"icon": "box",
"menuType": "dropdown",
"SubmenuCommands": [
{
"id": "editing-toolbar:get-plain-text",
"name": "Get Plain Text",
"icon": "lucide-file-text"
},
{
"id": "editing-toolbar:smart-symbols",
"name": "Full Half Converter",
"icon": "lucide-at-sign"
},
{
"id": "editingToolbar-Divider-Line",
"name": "Line Operations",
"icon": "vertical-split"
},
{
"id": "editing-toolbar:insert-blank-lines",
"name": "Insert Blank Lines",
"icon": "lucide-space"
},
{
"id": "editing-toolbar:remove-blank-lines",
"name": "Remove Blank Lines",
"icon": "lucide-minimize-2"
},
{
"id": "editing-toolbar:split-lines",
"name": "Split Lines",
"icon": "lucide-split"
},
{
"id": "editing-toolbar:merge-lines",
"name": "Merge Lines",
"icon": "lucide-merge"
},
{
"id": "editing-toolbar:dedupe-lines",
"name": "Dedupe Lines",
"icon": "lucide-filter"
},
{
"id": "editingToolbar-Divider-Line",
"name": "Text Processing",
"icon": "vertical-split"
},
{
"id": "editing-toolbar:add-wrap",
"name": "Add Prefix/Suffix",
"icon": "lucide-wrap-text"
},
{
"id": "editing-toolbar:number-lines",
"name": "Number Lines (Custom)",
"icon": "lucide-list-ordered"
},
{
"id": "editing-toolbar:remove-whitespace-trim",
"name": "Trim Line Ends",
"icon": "lucide-scissors"
},
{
"id": "editing-toolbar:remove-whitespace-compress",
"name": "Shrink Extra Spaces",
"icon": "lucide-minimize"
},
{
"id": "editing-toolbar:remove-whitespace-all",
"name": "Remove All Whitespace",
"icon": "lucide-eraser"
},
{
"id": "editingToolbar-Divider-Line",
"name": "Advanced Tools",
"icon": "vertical-split"
},
{
"id": "editing-toolbar:list-to-table",
"name": "List to Table",
"icon": "lucide-table"
},
{
"id": "editing-toolbar:table-to-list",
"name": "Table to List",
"icon": "lucide-list"
},
{
"id": "editing-toolbar:extract-between",
"name": "Extract Between Strings",
"icon": "lucide-brackets"
}
]
},
{
"id": "SubmenuCommands-lucdf3en5",
"name": "submenu",
"icon": "edit",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor-cut",
"name": "Cut",
"icon": "lucide-scissors"
},
{
"id": "editing-toolbar:editor-copy",
"name": "Copy",
"icon": "lucide-copy"
},
{
"id": "editing-toolbar:editor-paste",
"name": "Paste",
"icon": "lucide-clipboard-type"
},
{
"id": "editing-toolbar:editor:swap-line-down",
"name": "Swap Line Down",
"icon": "lucide-corner-right-down"
},
{
"id": "editing-toolbar:editor:swap-line-up",
"name": "Swap Line Up",
"icon": "lucide-corner-right-up"
}
]
},
{
"id": "editing-toolbar:editor:attach-file",
"name": "Attach File",
"icon": "lucide-paperclip"
},
{
"id": "editing-toolbar:editor:insert-table",
"name": "Insert Table",
"icon": "lucide-table"
},
{
"id": "editing-toolbar:editor:cycle-list-checklist",
"name": "Cycle List and Checklist",
"icon": "check-circle"
},
{
"id": "SubmenuCommands-luc8efull",
"name": "submenu",
"icon": "message-square",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor:toggle-blockquote",
"name": "Blockquote",
"icon": "lucide-text-quote"
},
{
"id": "editing-toolbar:insert-callout",
"name": "Callout",
"icon": "lucide-quote"
}
]
},
{
"id": "SubmenuCommands-mdcmder",
"name": "submenu",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M464 608 l0 -568 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-80 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 568 l-232 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 80 q0 3 2.5 5.5 q2.5 2.5 5.5 2.5 l560 0 q3 0 5.5 -2.5 q2.5 -2.5 2.5 -5.5 l0 -80 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-232 0 ZM864 696 q17 0 28.5 11.5 q11.5 11.5 11.5 28.5 q0 17 -11.5 28.5 q-11.5 11.5 -28.5 11.5 q-17 0 -28.5 -11.5 q-11.5 -11.5 -11.5 -28.5 q0 -17 11.5 -28.5 q11.5 -11.5 28.5 -11.5 ZM864 640 q-40 0 -68 28 q-28 28 -28 68 q0 40 28 68 q28 28 68 28 q40 0 68 -28 q28 -28 28 -68 q0 -40 -28 -68 q-28 -28 -68 -28 ZM576 322 l0 -63 q0 -3 2 -5 l89 -70 l-89 -70 q-2 -2 -2 -5 l0 -63 q0 -4 3.5 -5.5 q3.5 -1.5 6.5 0.5 l170 133 q4 3 4.5 8.5 q0.5 5.5 -2.5 9.5 l-2 2 l-170 133 q-3 2 -6.5 0.5 q-3.5 -1.5 -3.5 -5.5 ZM256 322 l0 -63 q0 -3 -2 -5 l-89 -70 l89 -70 q2 -2 2 -5 l0 -63 q0 -4 -3.5 -5.5 q-3.5 -1.5 -6.5 0.5 l-170 133 q-4 3 -4.5 8.5 q-0.5 5.5 2.5 9.5 l2 2 l170 133 q3 2 6.5 0.5 q3.5 -1.5 3.5 -5.5 Z\"></path></g></svg>",
"SubmenuCommands": [
{
"id": "editing-toolbar:superscript",
"name": "Superscript",
"icon": "superscript-glyph"
},
{
"id": "editing-toolbar:subscript",
"name": "Subscript",
"icon": "subscript-glyph"
},
{
"id": "editing-toolbar:editor:toggle-code",
"name": "Inline Code",
"icon": "code-glyph"
},
{
"id": "editing-toolbar:codeblock",
"name": "Code Block",
"icon": "codeblock-glyph"
},
{
"id": "editing-toolbar:editor:insert-wikilink",
"name": "Wikilink",
"icon": "<svg width=\"15\" height=\"15\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M306 134 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 7 q0 -8 -5 -8 l-45 0 q-5 0 -5 8 l0 784 q0 8 5 8 l45 0 q5 0 5 -8 q0 8 1 8 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 -623 q0 8 1 8 ZM139 134 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 7 q0 -8 -5 -8 l-45 0 q-5 0 -5 8 l0 784 q0 8 5 8 l45 0 q5 0 5 -8 q0 8 1 8 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 -623 q0 8 1 8 ZM711 134 q1 0 1 -8 l0 623 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 q1 0 1 -8 q0 8 4 8 l46 0 q4 0 4 -8 l0 -784 q0 -8 -4 -8 l-46 0 q-4 0 -4 8 q0 -7 -1 -7 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 ZM878 134 q1 0 1 -8 l0 623 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 q1 0 1 -8 q0 8 5 8 l45 0 q4 0 4 -8 l0 -784 q0 -8 -4 -8 l-45 0 q-5 0 -5 8 q0 -7 -1 -7 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:editor:insert-embed",
"name": "Embed",
"icon": "note-glyph"
},
{
"id": "editing-toolbar:insert-link",
"name": "Link",
"icon": "link-glyph"
},
{
"id": "editing-toolbar:hrline",
"name": "Horizontal Divider",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M912 424 l0 -80 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-784 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 80 q0 3 2.5 5.5 q2.5 2.5 5.5 2.5 l784 0 q3 0 5.5 -2.5 q2.5 -2.5 2.5 -5.5 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:toggle-inline-math",
"name": "Inline Math",
"icon": "lucide-sigma"
},
{
"id": "editing-toolbar:editor:insert-mathblock",
"name": "MathBlock",
"icon": "lucide-sigma-square"
}
]
},
{
"id": "SubmenuCommands-list",
"name": "submenu-list",
"icon": "bullet-list-glyph",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor:toggle-checklist-status",
"name": "Checklist",
"icon": "checkbox-glyph"
},
{
"id": "editing-toolbar:renumber-ordered-list",
"name": "Renumber Ordered List",
"icon": "list-restart"
},
{
"id": "editing-toolbar:toggle-numbered-list",
"name": "Ordered List",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M860 424 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM860 756 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM860 92 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM264 136 l-3 -3 l-51 -57 l56 0 q14 0 24.5 -10 q10.5 -10 11.5 -25 l0 -1 q0 -15 -10.5 -25.5 q-10.5 -10.5 -24.5 -10.5 l-137 0 q-15 0 -25 10 q-10 10 -11 24.5 q-1 14.5 9 25.5 l63 70 l49 54 q7 7 7 16.5 q0 9.5 -7.5 16.5 q-7.5 7 -18.5 7 q-11 0 -18.5 -6.5 q-7.5 -6.5 -8.5 -16.5 l0 0 q0 -15 -10.5 -25.5 q-10.5 -10.5 -25.5 -10.5 q-15 0 -25.5 10.5 q-10.5 10.5 -10.5 25.5 q0 26 13.5 47.5 q13.5 21.5 36 34.5 q22.5 13 49 13 q26.5 0 49.5 -13 q23 -13 36 -34.5 q13 -21.5 13 -47.5 q0 -20 -7.5 -37.5 q-7.5 -17.5 -21.5 -30.5 l-1 -1 ZM173 794 q11 11 25 10.5 q14 -0.5 24.5 -10.5 q10.5 -10 10.5 -25 l0 -293 q0 -15 -10 -25.5 q-10 -10.5 -25 -10.5 q-15 0 -25.5 10 q-10.5 10 -11.5 25 l0 211 q-10 -8 -23.5 -7 q-13.5 1 -22.5 11 l-1 0 q-10 11 -9.5 25.5 q0.5 14.5 10.5 24.5 l58 54 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:toggle-bullet-list",
"name": "Unordered List",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M860 424 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM860 756 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM860 92 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM176 716 l0 0 ZM112 716 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 ZM176 384 l0 0 ZM112 384 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 ZM176 52 l0 0 ZM112 52 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:undent-list",
"name": "Unindent List",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 302 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 542 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 784 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 62 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM244 534 l-123 -122 q-8 -7 -8 -18 q0 -11 8 -18 l123 -122 q8 -7 19 -7 q11 0 18.5 7.5 q7.5 7.5 7.5 18.5 l0 242 q0 11 -7.5 18.5 q-7.5 7.5 -18.5 7.5 q-11 0 -19 -7 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:indent-list",
"name": "Indent list",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 302 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 542 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 784 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 62 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM158 534 l124 -122 q7 -7 7 -18 q0 -11 -7 -18 l-124 -122 q-7 -7 -18 -7 q-11 0 -19 7.5 q-8 7.5 -8 18.5 l0 242 q0 11 8 18.5 q8 7.5 19 7.5 q11 0 18 -7 Z\"></path></g></svg>"
}
]
},
{
"id": "SubmenuCommands-aligin",
"name": "submenu-aligin",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M724 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM724 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>",
"SubmenuCommands": [
{
"id": "editing-toolbar:justify",
"name": "Justify Text",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M112 736 l0 0 ZM120 736 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 331 l0 0 ZM120 331 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 128 l0 0 ZM120 128 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 533 l0 0 ZM120 533 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:left",
"name": "Align Text Left",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M572 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM572 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:center",
"name": "Center Text",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M724 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM724 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:right",
"name": "Align Text Right",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
}
]
},
{
"id": "editing-toolbar:change-font-color",
"name": "Change Font Color",
"icon": "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" focusable=\"false\" fill=\"currentColor\"><g fill-rule=\"evenodd\"><path id=\"change-font-color-icon\" d=\"M3 18h18v3H3z\" style=\"fill:#2DC26B\"></path><path d=\"M8.7 16h-.8a.5.5 0 01-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 01-.5.6h-.8a.5.5 0 01-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4zm2.6-7.6l-.6 2a.5.5 0 00.5.6h1.6a.5.5 0 00.5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4z\"></path></g></svg>"
},
{
"id": "editing-toolbar:change-background-color",
"name": "Change Background Color",
"icon": "<svg width=\"18\" height=\"24\" viewBox=\"0 0 256 256\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"none\" stroke-width=\"1\" fill=\"currentColor\" fill-rule=\"evenodd\"><g ><g fill=\"currentColor\"><g transform=\"translate(119.502295, 137.878331) rotate(-135.000000) translate(-119.502295, -137.878331) translate(48.002295, 31.757731)\" ><path d=\"M100.946943,60.8084699 L43.7469427,60.8084699 C37.2852111,60.8084699 32.0469427,66.0467383 32.0469427,72.5084699 L32.0469427,118.70847 C32.0469427,125.170201 37.2852111,130.40847 43.7469427,130.40847 L100.946943,130.40847 C107.408674,130.40847 112.646943,125.170201 112.646943,118.70847 L112.646943,72.5084699 C112.646943,66.0467383 107.408674,60.8084699 100.946943,60.8084699 Z M93.646,79.808 L93.646,111.408 L51.046,111.408 L51.046,79.808 L93.646,79.808 Z\" fill-rule=\"nonzero\"></path><path d=\"M87.9366521,16.90916 L87.9194966,68.2000001 C87.9183543,69.4147389 86.9334998,70.399264 85.7187607,70.4 L56.9423078,70.4 C55.7272813,70.4 54.7423078,69.4150264 54.7423078,68.2 L54.7423078,39.4621057 C54.7423078,37.2523513 55.5736632,35.1234748 57.0711706,33.4985176 L76.4832996,12.4342613 C78.9534987,9.75382857 83.1289108,9.5834005 85.8093436,12.0535996 C87.1658473,13.303709 87.9372691,15.0644715 87.9366521,16.90916 Z\" fill-rule=\"evenodd\"></path><path d=\"M131.3,111.241199 L11.7,111.241199 C5.23826843,111.241199 0,116.479467 0,122.941199 L0,200.541199 C0,207.002931 5.23826843,212.241199 11.7,212.241199 L131.3,212.241199 C137.761732,212.241199 143,207.002931 143,200.541199 L143,122.941199 C143,116.479467 137.761732,111.241199 131.3,111.241199 Z M124,130.241 L124,193.241 L19,193.241 L19,130.241 L124,130.241 Z\" fill-rule=\"nonzero\"></path></g></g><path d=\"M51,218 L205,218 C211.075132,218 216,222.924868 216,229 C216,235.075132 211.075132,240 205,240 L51,240 C44.9248678,240 40,235.075132 40,229 C40,222.924868 44.9248678,218 51,218 Z\" id=\"change-background-color-icon\" style=\"fill:#FA541C\"></path></g></g></svg>"
},
{
"id": "editing-toolbar:fullscreen-focus",
"name": "Fullscreen Focus Mode",
"icon": "fullscreen"
},
{
"id": "editing-toolbar:workplace-fullscreen-focus",
"name": "Workplace Fullscreen",
"icon": "exit-fullscreen"
}
],
"followingCommands": [],
"topCommands": [],
"fixedCommands": [],
"mobileCommands": [],
"enableMultipleConfig": false,
"enableTopToolbar": true,
"enableFollowingToolbar": false,
"enableFixedToolbar": false,
"appendMethod": "workspace",
"shouldShowMenuOnSelect": false,
"cMenuVisibility": true,
"cMenuBottomValue": 4.25,
"cMenuNumRows": 12,
"cMenuWidth": 610,
"cMenuFontColor": "#2DC26B",
"cMenuBackgroundColor": "#d3f8b6",
"autohide": false,
"Iscentered": false,
"custom_bg1": "#FFB78B8C",
"custom_bg2": "#CDF4698C",
"custom_bg3": "#A0CCF68C",
"custom_bg4": "#F0A7D88C",
"custom_bg5": "#ADEFEF8C",
"custom_fc1": "#D83931",
"custom_fc2": "#DE7802",
"custom_fc3": "#245BDB",
"custom_fc4": "#6425D0",
"custom_fc5": "#646A73",
"isLoadOnMobile": false,
"horizontalPosition": 0,
"verticalPosition": 0,
"formatBrushes": {},
"customCommands": [],
"viewTypeSettings": {},
"appearanceByStyle": {
"top": {
"toolbarBackgroundColor": "rgba(var(--background-secondary-rgb), 0.7)",
"toolbarIconColor": "var(--text-normal)",
"toolbarIconSize": 18,
"aestheticStyle": "default"
},
"following": {
"toolbarBackgroundColor": "rgba(var(--background-secondary-rgb), 0.7)",
"toolbarIconColor": "var(--text-normal)",
"toolbarIconSize": 18,
"aestheticStyle": "default"
},
"fixed": {
"toolbarBackgroundColor": "rgba(var(--background-secondary-rgb), 0.7)",
"toolbarIconColor": "var(--text-normal)",
"toolbarIconSize": 18,
"aestheticStyle": "default"
},
"mobile": {
"toolbarBackgroundColor": "rgba(var(--background-secondary-rgb), 0.7)",
"toolbarIconColor": "var(--text-normal)",
"toolbarIconSize": 18,
"aestheticStyle": "default"
}
},
"toolbarBackgroundColor": "rgba(var(--background-secondary-rgb), 0.7)",
"toolbarIconColor": "var(--text-normal)",
"toolbarIconSize": 18,
"useCurrentLineForRegex": false,
"ai": {
"enabled": false,
"consentAccepted": false,
"onboardingShown": true,
"providerMode": "pkmer-first",
"enableInlineCompletion": true,
"inlineCompletionHintLearned": false,
"completionTrigger": "manual",
"completionDelay": 500,
"enableRewrite": true,
"showRewriteToolbarOnSelection": false,
"rewriteMinSelectionLength": 1,
"pkmerApiBaseUrl": "https://newapi.pkmer.cn",
"pkmerModel": "04-fast",
"pkmerModelRouting": {
"mode": "smart",
"completion": "04-fast",
"rewrite": "04-fast",
"reasoning": "03-agent",
"artifact": "03-agent"
},
"pkmer": {
"tokenExpiresAt": 0,
"userInfo": null
},
"enableCustomModel": false,
"customModel": {
"apiFormat": "openai-compatible",
"baseUrl": "",
"apiKey": "",
"model": "",
"temperature": 0.2
},
"customPromptHistory": [],
"customPromptTemplates": [
{
"id": "template-demo-variables",
"name": "📝 Summarize Key Points",
"prompt": "Analyze the structure of {{file:content}} and focus on:\n{{selection}}\n\nPlease provide:\n1. A concise overview\n2. The key points\n3. Suggestions for improvement",
"icon": "lucide-sparkles"
},
{
"id": "template-task-variables",
"name": "Extract Tasks",
"prompt": "Today's date is {{date}}. Extract all actionable tasks from {{file:content}}, with special attention to:\n{{selection}}\n\nPlease output strictly in Obsidian Tasks plugin format, one task per line:\n\n- [ ] Task description ⏫/🔼/🔽/⏬ priority\n- [ ] Task description 📅 YYYY-MM-DD due date\n- [ ] Task description ⏰ YYYY-MM-DD HH:mm reminder\n- [ ] Task description 🛫 YYYY-MM-DD start date\n- [ ] Task description 🔁 every day/week/month recurrence\n- [ ] Task description #tag #project\n\nExtraction rules:\n1. If the text implies urgency such as urgent, ASAP, immediately, or today, add ⏫.\n2. If it implies near-term timing such as tomorrow, this week, or soon, add 🔼.\n3. Convert explicit dates to 📅 YYYY-MM-DD.\n4. Convert explicit times to ⏰ YYYY-MM-DD HH:mm when possible.\n5. Add recurrence for repeated work such as 🔁 every week/month.\n6. Add practical tags for each task.\n\nExample output:\n- [ ] Finish project report ⏫ 📅 2026-04-25 #work\n- [ ] Weekly team sync 🔁 every week on Monday ⏰ 09:00 #meeting\n- [ ] Follow up on client request 🔼 📅 2026-04-23 #follow-up",
"icon": "lucide-sparkles"
},
{
"id": "template-dataview",
"name": "Generate Dataview",
"prompt": "Help me generate an Obsidian Dataview query block based on my requirement. Requirements:\n1. Use DataviewJS or DQL syntax.\n2. Include the necessary filters and sorting.\n3. Add short comments explaining each part.\n4. Use DataviewJS if the logic is complex.\n\nMy requirement:",
"icon": "lucide-database"
},
{
"id": "template-templater",
"name": "Design Templater Template",
"prompt": "Help me design an Obsidian Templater template. Requirements:\n1. Use Templater syntax (<% %>).\n2. Include dynamic date, time, and similar variables.\n3. Support user input prompts.\n4. Add necessary conditionals and loops.\n5. Comment the purpose of each section.\n\nTemplate purpose:",
"icon": "lucide-file-code"
},
{
"id": "template-mermaid",
"name": "Create Mermaid Diagram",
"prompt": "Based on my selected text {{selection}}, generate Mermaid diagram code. Requirements:\n1. Choose an appropriate diagram type such as flowchart, sequence, class, or gantt.\n2. Use clear node names.\n3. Add useful styling and comments when needed.\n4. Ensure the syntax is valid and renderable.\n",
"icon": "lucide-workflow"
},
{
"id": "template-metadata",
"name": "Design YAML",
"prompt": "Based on the current note content {{file:content}}, help me design a suitable YAML Frontmatter structure for this note. Requirements:\n1. Recommend fields that fit the note content.\n2. Include common fields such as tags, aliases, and date.\n3. Suggest useful custom fields.\n4. Briefly explain the purpose of each field.\n\nNote type:",
"icon": "lucide-file-json"
},
{
"id": "template-callout",
"name": "Wrap with Callout",
"prompt": "Based on my selected text {{selection}}, wrap it using an Obsidian Callout block. Requirements:\n1. Choose an appropriate callout type such as note, tip, warning, or danger.\n2. Support nesting and folding when helpful.\n3. Include a title and content.\n4. Allow code blocks or lists when needed.\n\nContent requirement:",
"icon": "lucide-message-square"
}
]
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "editing-toolbar",
"name": "Editing Toolbar",
"version": "4.0.8",
"minAppVersion": "0.14.0",
"description": "The Obsidian Editing Toolbar is modified from cmenu, which provides more powerful customization settings and has many built-in editing commands to be a MS Word-like toolbar editing experience.",
"author": "Cuman",
"authorUrl": "https://github.com/cumany/obsidian-editing-toolbar",
"isDesktopOnly": false
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,758 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
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);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => HeadingIndent
});
module.exports = __toCommonJS(main_exports);
var import_obsidian2 = require("obsidian");
// src/editingMode.ts
var import_language = require("@codemirror/language");
var import_state = require("@codemirror/state");
var import_view = require("@codemirror/view");
// src/FrontmatterListener.ts
var FrontmatterListener = class {
constructor(app) {
this.currentIndentState = null;
this.currentFile = null;
this.listeners = [];
this.fileChanged = false;
this.valueChanged = false;
this.eventRefs = [];
this.app = app;
}
/**
* Update current value and detect whether `heading-indent` has changed
*/
update() {
const prevIndentState = this.currentIndentState;
const prevFile = this.currentFile;
const currentFile = this.app.workspace.getActiveFile();
this.currentFile = currentFile;
if (currentFile) {
const metadata = this.app.metadataCache.getFileCache(currentFile);
const frontmatter = metadata == null ? void 0 : metadata.frontmatter;
this.currentIndentState = (frontmatter == null ? void 0 : frontmatter["heading-indent"]) !== void 0 ? String(frontmatter["heading-indent"]) : "1";
} else {
this.currentIndentState = null;
}
this.fileChanged = prevFile !== currentFile;
this.valueChanged = this.currentIndentState !== prevIndentState;
if (this.valueChanged) {
this.notifyListeners(this.currentIndentState, prevIndentState, currentFile, prevFile);
}
return this.currentIndentState;
}
/**
* Add a listener callback
*/
addListener(callback) {
this.listeners.push(callback);
}
/**
* Remove a listener callback
*/
removeListener(callback) {
const index = this.listeners.indexOf(callback);
if (index > -1) {
this.listeners.splice(index, 1);
}
}
/**
* Notify all registered listeners
*/
notifyListeners(newValue, oldValue, newFile, oldFile) {
this.listeners.forEach((listener) => {
try {
listener(newValue, oldValue, newFile, oldFile);
} catch (error) {
console.error("Listener execution error:", error);
}
});
}
/**
* Determines if heading indentation should be applied to the current file.
*
* Checks frontmatter field 'heading-indent':
* - false/0: disabled
* - Any other value or missing: enabled (default)
*
* @returns true if indentation should be applied
*/
isIndentEnabled() {
if (this.currentIndentState === null) {
return false;
}
const val = String(this.currentIndentState).toLowerCase();
return !(val === "false" || val === "0");
}
/**
* Start listening to workspace and metadata changes
*/
start() {
const leafChangeRef = this.app.workspace.on("active-leaf-change", () => {
this.update();
});
this.eventRefs.push(leafChangeRef);
const metadataChangeRef = this.app.metadataCache.on("changed", (file) => {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile && activeFile.path === file.path) {
this.update();
}
});
this.eventRefs.push(metadataChangeRef);
this.update();
}
/**
* Stop listening and clean up event handlers
*/
stop() {
this.eventRefs.forEach((ref) => this.app.workspace.offref(ref));
this.eventRefs = [];
}
};
var _listener = null;
function initFrontmatterListener(app) {
if (!_listener) {
_listener = new FrontmatterListener(app);
}
}
function getFrontmatterListener() {
if (!_listener) {
throw new Error("FrontmatterListener not initialized");
}
return _listener;
}
function cleanupFrontmatterListener() {
if (_listener) {
_listener.stop();
_listener = null;
}
}
// src/editingMode.ts
var indentStateField = import_state.StateField.define({
create(state) {
return getDecorationSet(state);
},
/**
* lifecicle for an update: DOM event -> transaction -> create new state -> view update
*/
update(currentValue, tr) {
let needUpdate = false;
for (const e of tr.effects) {
if (e.is(updateNeededNotificationEffect)) {
needUpdate = true;
break;
}
}
if (!needUpdate && syntaxTreeChanged(tr)) {
needUpdate = true;
}
if (needUpdate) {
const newValue = getDecorationSet(tr.state);
const isIndentEnabled = getFrontmatterListener().isIndentEnabled();
const newHasDecorations = newValue.decorations.size > 0;
if (isIndentEnabled && !newHasDecorations)
return currentValue;
else
return newValue;
}
return currentValue;
},
provide(field) {
return import_view.EditorView.decorations.from(field, (value) => value.decorations);
}
});
function syntaxTreeChanged(tr) {
const oldTree = (0, import_language.syntaxTree)(tr.startState);
const newTree = (0, import_language.syntaxTree)(tr.state);
return oldTree !== newTree;
}
function getDecorationSet(state) {
var _a;
if (!getFrontmatterListener().isIndentEnabled())
return { decorations: import_view.Decoration.none, intervals: [] };
const settings = window.app.plugins.plugins["heading-level-indent"].settings;
const headings = [];
let highestLevelInDocument = 6;
(0, import_language.syntaxTree)(state).iterate({
enter(node) {
if (node.type.name.startsWith("HyperMD-header_HyperMD-header-")) {
const lineAt = state.doc.lineAt(node.from);
const text = state.doc.sliceString(node.from, node.to);
const level = Number(node.type.name.slice(-1));
const posAt = node.from;
headings.push({
text,
level,
headingLineNumber: lineAt.number,
headingPos: posAt
});
highestLevelInDocument = Math.min(highestLevelInDocument, level);
}
}
});
if (settings.treatHighestPresentHeadingAsH1) {
for (const heading of headings) {
heading.level -= highestLevelInDocument - 1;
}
}
const builder = new import_state.RangeSetBuilder();
const el = document.querySelector(".workspace-leaf.mod-active .cm-content");
if (el === null) return { decorations: import_view.Decoration.none, intervals: [] };
const containerWidth = parseInt(getComputedStyle(el).width);
const intervals = [];
for (const [index, heading] of headings.entries()) {
const { level, headingLineNumber, headingPos } = heading;
const headingLine = state.doc.line(headingLineNumber);
const firstDataLineNumber = headingLineNumber + 1;
const lastDataLineNumber = ((_a = headings[index + 1]) == null ? void 0 : _a.headingLineNumber) - 1 || state.doc.lines;
const pxForDataLine = settings[`h${level}`] || 0;
const pxForHeadingLine = settings[`h${level - 1}` || 0];
intervals.push([headingPos, pxForDataLine]);
const dataStyles = `left:${pxForDataLine}px;width:${containerWidth - pxForDataLine}px;`;
const headingStyles = `left:${pxForHeadingLine}px;width:${containerWidth - pxForHeadingLine}px;`;
builder.add(
headingLine.from,
headingLine.from,
import_view.Decoration.line({
attributes: { style: headingStyles }
})
);
for (let j = firstDataLineNumber; j < lastDataLineNumber + 1; j++) {
const dataLine = state.doc.line(j);
builder.add(
dataLine.from,
dataLine.from,
import_view.Decoration.line({
attributes: { style: dataStyles }
})
);
}
}
return { decorations: builder.finish(), intervals };
}
var indentEmbedsPlugin = import_view.ViewPlugin.fromClass(
class {
constructor(view) {
this.view = view;
this.scheduleIndentEmbedsAfterRender();
}
update(update) {
for (const tr of update.transactions) {
for (const e of tr.effects) {
if (e.is(updateNeededNotificationEffect)) {
this.scheduleIndentEmbedsAfterRender();
}
}
}
if (update.docChanged || update.viewportChanged) {
this.scheduleIndentEmbedsAfterRender();
}
}
scheduleIndentEmbedsAfterRender() {
this.view.requestMeasure({
read: () => {
},
write: (measure, view) => {
const { intervals } = view.state.field(indentStateField);
const dom = this.view.dom;
const el = document.querySelector(".workspace-leaf.mod-active .cm-content");
if (el === null) return;
const containerWidth = parseInt(getComputedStyle(el).width);
const embeds = Array.from(
dom.querySelectorAll("div.cm-content > div.cm-embed-block")
);
const mathBlocks = Array.from(
dom.querySelectorAll("div.cm-content > div.math-block")
);
let prevIntervalIndex = 0;
for (const embed of [...embeds, ...mathBlocks]) {
const [intervalIndex, offset] = findIntervalOffset(
intervals,
view.posAtDOM(embed),
prevIntervalIndex
);
prevIntervalIndex = intervalIndex;
embed.style.left = `${offset}px`;
embed.style.width = `${containerWidth - offset}px`;
}
const internalEmbeds = Array.from(
dom.querySelectorAll("div.cm-content > div.internal-embed")
);
prevIntervalIndex = 0;
for (const embed of internalEmbeds) {
const [intervalIndex, offset] = findIntervalOffset(
intervals,
view.posAtDOM(embed),
prevIntervalIndex
);
prevIntervalIndex = intervalIndex;
embed.style.position = "relative";
embed.style.left = `${offset}px`;
embed.style.width = `${containerWidth - offset}px`;
}
const imgs = Array.from(
dom.querySelectorAll("div.cm-content > img")
);
prevIntervalIndex = 0;
for (const img of imgs) {
const [intervalIndex, offset] = findIntervalOffset(
intervals,
view.posAtDOM(img),
prevIntervalIndex
);
prevIntervalIndex = intervalIndex;
img.style.position = "relative";
img.style.left = `${offset}px`;
img.style.maxWidth = `${containerWidth - offset}px`;
}
}
});
}
}
);
function findIntervalOffset(intervals, pos, start) {
if (!intervals.length || pos < intervals[0][0]) {
return [0, 0];
}
let low = start;
let high = intervals.length - 1;
let result = [0, 0];
while (low <= high) {
const mid = low + high >> 1;
const [midPos, midOffset] = intervals[mid];
if (midPos < pos) {
result = [mid, midOffset];
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
var updateNeededNotificationEffect = import_state.StateEffect.define();
var resizeNotificationPlugin = import_view.ViewPlugin.define((view) => {
let resizeTimeout;
const observer = new ResizeObserver((entries) => {
clearTimeout(resizeTimeout);
resizeTimeout = window.setTimeout(() => {
view.dispatch({
effects: updateNeededNotificationEffect.of()
});
}, 100);
});
observer.observe(view.dom);
return {
destroy() {
observer.disconnect();
}
};
});
// src/renderedMode.ts
var RenderedModeIndenter = class {
/**
* Apply indentation to markdown elements in reading view or PDF export.
* Works by processing the DOM after Obsidian renders the markdown.
*/
static applyIndent(element, settings) {
try {
if (!getFrontmatterListener().isIndentEnabled()) return;
} catch (e) {
console.warn("FrontmatterListener not initialized, applying indent by default");
}
this.currentSettings = settings;
if (this.processingInProgress) return;
const rootContainer = element.closest(".markdown-preview-view");
if (!rootContainer) return;
this.setupObserver(rootContainer, settings);
this.processingInProgress = true;
requestAnimationFrame(() => {
const processor = new IndentProcessor(settings, rootContainer);
processor.process();
this.processingInProgress = false;
});
}
/**
* Set up MutationObserver to watch for DOM changes when scrolling in virtualized documents.
* Obsidian only renders viewport content in large documents, adding/removing nodes as you scroll.
*/
static setupObserver(rootContainer, settings) {
const previewSection = rootContainer.querySelector(".markdown-preview-section");
if (!previewSection) return;
this.setupObserverForSection(previewSection, rootContainer, settings);
}
/**
* Set up a global observer that watches for new preview sections across all markdown views.
* This ensures observers are attached when switching files or opening new views.
*/
static setupGlobalObserver(app, getSettings) {
const workspaceContainer = document.querySelector(".workspace");
if (!workspaceContainer) return;
const globalObserver = new MutationObserver(() => {
const previewSections = document.querySelectorAll(".markdown-preview-section");
previewSections.forEach((section) => {
if (!this.observers.has(section)) {
const rootContainer = section.closest(".markdown-preview-view");
if (rootContainer) {
this.setupObserverForSection(section, rootContainer, getSettings());
}
}
});
});
globalObserver.observe(workspaceContainer, { childList: true, subtree: true });
this.observers.set(workspaceContainer, globalObserver);
const existingSections = document.querySelectorAll(".markdown-preview-section");
existingSections.forEach((section) => {
const rootContainer = section.closest(".markdown-preview-view");
if (rootContainer) {
this.setupObserverForSection(section, rootContainer, getSettings());
}
});
}
/**
* Set up observer for a specific preview section
*/
static setupObserverForSection(previewSection, rootContainer, settings) {
if (this.observers.has(previewSection)) return;
const observer = new MutationObserver((mutations) => {
const hasChildListChanges = mutations.some((m) => m.type === "childList");
if (!hasChildListChanges) return;
if (!this.processingInProgressForObserver) {
this.processingInProgressForObserver = true;
requestAnimationFrame(() => {
const processor = new IndentProcessor(settings, rootContainer);
if (getFrontmatterListener().isIndentEnabled()) {
processor.process();
} else {
processor.clear();
}
this.processingInProgressForObserver = false;
});
}
});
observer.observe(previewSection, { childList: true });
this.observers.set(previewSection, observer);
}
/**
* Remove indentation from all preview views of the current file
*/
static clearCurrentView() {
const allPreviewViews = activeDocument.querySelectorAll(".markdown-preview-view");
allPreviewViews.forEach((previewView) => {
const processor = new IndentProcessor(null, previewView);
processor.clear();
});
}
/**
* Apply indentation to all preview views of the current file
*/
static applyToCurrentView(settings) {
const allPreviewViews = activeDocument.querySelectorAll(".markdown-preview-view");
allPreviewViews.forEach((previewView) => {
const processor = new IndentProcessor(settings, previewView);
processor.process();
});
}
/**
* Disconnect all MutationObservers and clear all indentation (call when plugin unloads)
*/
static cleanup() {
this.observers.forEach((observer) => observer.disconnect());
this.observers.clear();
this.currentSettings = null;
const allPreviewViews = document.querySelectorAll(".markdown-preview-view");
allPreviewViews.forEach((previewView) => {
const processor = new IndentProcessor(null, previewView);
processor.clear();
});
}
};
RenderedModeIndenter.processingInProgress = false;
RenderedModeIndenter.processingInProgressForObserver = false;
RenderedModeIndenter.observers = /* @__PURE__ */ new Map();
RenderedModeIndenter.currentSettings = null;
var IndentProcessor = class {
constructor(settings, rootElement) {
this.settings = settings;
this.rootElement = rootElement;
this.currentHeadingLevel = 0;
this.lastHeadingElement = null;
}
process() {
const selectors = this.getContentSelectors();
const elements = this.rootElement.querySelectorAll(
selectors.map((tag) => `div > ${tag}`).join(", ")
);
for (const element of Array.from(elements)) {
if (this.shouldSkipElement(element)) {
continue;
}
const tagName = element.tagName.toLowerCase();
if (this.isHeading(tagName)) {
this.processHeading(element, tagName);
} else if (this.currentHeadingLevel > 0) {
this.processContent(element);
}
}
}
/**
* Remove all indentation styles and classes
*/
clear() {
const elDivs = this.rootElement.querySelectorAll('div[class*="el-"]');
for (const div of Array.from(elDivs)) {
const htmlDiv = div;
htmlDiv.style.paddingLeft = "";
const classesToRemove = [];
htmlDiv.classList.forEach((className) => {
if (className.startsWith("heading_") || className.startsWith("data_")) {
classesToRemove.push(className);
}
});
classesToRemove.forEach((className) => htmlDiv.classList.remove(className));
}
}
getContentSelectors() {
return [
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"p",
"ul",
"ol",
"blockquote",
"table",
"pre",
"div.callout"
];
}
shouldSkipElement(element) {
const isPdfExport = this.rootElement.closest(".print") !== null;
if (isPdfExport && element.classList.contains("__title__")) {
return true;
}
return false;
}
isHeading(tagName) {
return /^h[1-6]$/.test(tagName);
}
processHeading(element, tagName) {
const level = parseInt(tagName.charAt(1));
this.currentHeadingLevel = level;
this.lastHeadingElement = element;
const parentDiv = element.parentElement;
if ((parentDiv == null ? void 0 : parentDiv.tagName) === "DIV") {
const indent = this.getIndentForLevel(level - 1);
parentDiv.style.paddingLeft = `${indent}px`;
parentDiv.classList.add(`heading_h${level}`);
}
}
processContent(element) {
var _a;
const parentDiv = element.parentElement;
if ((parentDiv == null ? void 0 : parentDiv.tagName) === "DIV" && parentDiv !== ((_a = this.lastHeadingElement) == null ? void 0 : _a.parentElement)) {
const indent = this.getIndentForLevel(this.currentHeadingLevel);
parentDiv.style.paddingLeft = `${indent}px`;
parentDiv.classList.add(`data_h${this.currentHeadingLevel}`);
}
}
getIndentForLevel(level) {
if (level === 0) return 0;
const key = `h${level}`;
return parseInt(String(this.settings[key])) || 0;
}
};
// src/settings.ts
var import_obsidian = require("obsidian");
var DEFAULT_SETTINGS = {
h1: "30",
h2: "50",
h3: "70",
h4: "90",
h5: "110",
h6: "130",
treatHighestPresentHeadingAsH1: false
};
var IndentSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h3", {
text: "Set indentation for the content of each heading in pixels"
});
containerEl.createEl("div", {
text: `Indentation applied for the heading lines itself will be the same as the
content of inmediately previous heading. For example, if the indentation
for the content of H3 is set to 70 pixels, H2 heading line itself
will be indented the same`,
attr: { style: "margin-bottom: 10px; color: gray;" }
});
new import_obsidian.Setting(containerEl).setName("Content under H1").addText(
(number) => number.setPlaceholder("").setValue(this.plugin.settings.h1).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h1 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Content under H2").addText(
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h2).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h2 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Content under H3").addText(
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h3).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h3 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Content under H4").addText(
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h4).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h4 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Content under H5").addText(
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h5).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h5 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Content under H6").addText(
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h6).onChange((value) => __async(this, null, function* () {
this.plugin.settings.h6 = value;
yield this.plugin.saveSettings();
}))
);
new import_obsidian.Setting(containerEl).setName("Treat the highest present heading in the document as H1 (editing mode only)").addToggle(
(toggle) => toggle.setValue(this.plugin.settings.treatHighestPresentHeadingAsH1).onChange((value) => __async(this, null, function* () {
this.plugin.settings.treatHighestPresentHeadingAsH1 = value;
yield this.plugin.saveSettings();
}))
);
}
};
// src/main.ts
var HeadingIndent = class extends import_obsidian2.Plugin {
// Configure resources needed by the plugin.
onload() {
return __async(this, null, function* () {
yield this.loadSettings();
this.addSettingTab(new IndentSettingTab(this.app, this));
initFrontmatterListener(this.app);
getFrontmatterListener().start();
this.registerEditorExtension(indentStateField);
this.registerEditorExtension(indentEmbedsPlugin);
this.registerEditorExtension(resizeNotificationPlugin);
this.registerMarkdownPostProcessor((element, _context) => {
RenderedModeIndenter.applyIndent(element, this.settings);
}, 10);
this.frontmatterChangeHandler = (_newValue, _oldValue, _newFile, _oldFile) => {
if (getFrontmatterListener().isIndentEnabled()) {
RenderedModeIndenter.applyToCurrentView(this.settings);
} else {
RenderedModeIndenter.clearCurrentView();
}
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
const view = (_a = leaf.view.editor) == null ? void 0 : _a.cm;
if (view) {
view.dispatch({
effects: updateNeededNotificationEffect.of()
});
}
});
};
getFrontmatterListener().addListener(this.frontmatterChangeHandler);
this.app.workspace.onLayoutReady(() => {
RenderedModeIndenter.setupGlobalObserver(this.app, () => this.settings);
});
});
}
/**
* Release any resources configured by the plugin; Automatically clean up registered event listeners
*/
onunload() {
if (this.frontmatterChangeHandler) {
getFrontmatterListener().removeListener(this.frontmatterChangeHandler);
}
cleanupFrontmatterListener();
RenderedModeIndenter.cleanup();
}
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);
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
const view = (_a = leaf.view.editor) == null ? void 0 : _a.cm;
if (view) {
view.dispatch({
effects: updateNeededNotificationEffect.of()
});
}
});
});
}
};
/* nosourcemap */

View file

@ -0,0 +1,10 @@
{
"id": "heading-level-indent",
"name": "Heading Level Indent",
"version": "3.0.0",
"minAppVersion": "0.12.0",
"description": "Indenting content under headers based on their level",
"author": "svonjoi",
"authorUrl": "https://github.com/svonjoi",
"isDesktopOnly": false
}

View file

@ -0,0 +1,9 @@
{
"citationExportFormat": "biblatex",
"literatureNoteTitleTemplate": "@{{citekey}}",
"literatureNoteFolder": "",
"literatureNoteContentTemplate": "---\ntitle: {{title}}\nauthors: {{authorString}}\nyear: {{year}}\n---\n\n",
"markdownCitationTemplate": "[@{{citekey}}]",
"alternativeMarkdownCitationTemplate": "@{{citekey}}",
"citationExportPath": "Thèse/these_ref.bib"
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-citation-plugin",
"name": "Citations",
"version": "0.4.5",
"minAppVersion": "0.9.20",
"description": "Automatically search and insert citations from a Zotero library",
"author": "Jon Gauthier",
"authorUrl": "http://foldl.me",
"isDesktopOnly": true
}

View file

@ -0,0 +1,114 @@
/** Citations modal **/
/*
* Loading animation from
* https://loading.io/css/
*/
.zoteroModalLoading {
color: var(--text-muted);
text-align: center;
}
.zoteroModalLoadingAnimation {
display: inline-block;
width: 80px;
height: 80px;
}
.zoteroModalLoadingAnimation {
content: " ";
display: block;
width: 32px;
height: 32px;
margin: 10px auto;
border-radius: 50%;
border: 3px solid #eee;
border-color: #eee transparent #eee transparent;
animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#zoteroSettingTab .text-monospace {
font-family: monospace;
}
.zoteroModalResults .suggestion-item {
height: fit-content;
line-height: 1.5rem;
}
.zoteroTitle {
font-size: 14px;
display: block;
}
.zoteroAuthors {
color: #555;
font-size: 13px;
}
.zoteroAuthorsEmpty::after {
font-style: italic;
content: 'Unknown authors';
}
.zoteroCitekey {
color: #555;
font-size: 13px;
font-family: monospace;
display: inline-block;
margin-right: 5px;
padding-right: 5px;
border-right: 1px solid #ccc;
}
.theme-dark .zoteroTitle {
font-size: 14px;
display: block;
}
.theme-dark .zoteroAuthors {
color: #aaa;
font-size: 13px;
}
.theme-dark .zoteroCitekey {
color: #aaa;
font-size: 13px;
font-family: monospace;
display: inline-block;
margin-right: 5px;
padding-right: 5px;
border-right: 1px solid #aaa;
}
/** Settings dialog **/
.d-none {
display: none;
}
.zoteroSettingCitationPathLoading,
.zoteroSettingCitationPathError,
.zoteroSettingCitationPathSuccess {
font-size: 14px;
}
.zoteroSettingCitationPathLoading {
color: var(--text-muted);
}
.zoteroSettingCitationPathError {
color: var(--text-error);
}
.zoteroSettingCitationPathError:hover {
color: var(--text-error-hover);
}
.zoteroSettingCitationPathSuccess {
color: var(--text-accent);
}
.zoteroSettingCitationPathSuccess:hover {
color: var(--text-accent-hover);
}
#zoteroSettingTab textarea {
resize: vertical;
width: 100%;
min-height: 10em;
}

View file

@ -0,0 +1,409 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
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, {
CustomFileExtensions: () => CustomFileExtensions,
default: () => main_default
});
module.exports = __toCommonJS(main_exports);
var import_obsidian3 = require("obsidian");
// src/settings.ts
var import_obsidian = require("obsidian");
var _DEFAULT_TYPES = {
"markdown": [
"",
"md",
"txt",
"js",
"css",
"ts",
"jsx",
"tsx",
"yaml",
"yml",
"sass",
"scss",
"tex",
"json",
"html"
]
};
var DEFAULT_SETTINGS = {
types: _DEFAULT_TYPES,
configIsValid: true,
errors: {},
allowMdOverride: false,
mobileSettings: {
enabled: false,
configIsValid: true,
types: _DEFAULT_TYPES
}
};
var CustomFileExtensionsSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this._defaults = void 0;
this.plugin = plugin;
}
display() {
const { containerEl } = this;
const example = JSON.stringify(DEFAULT_SETTINGS.types, null, 2);
containerEl.empty();
containerEl.createEl("h2", { text: "Custom File Extensions Settings" });
this._config = new import_obsidian.Setting(containerEl).setName("Config").setDesc("Valid entry is a JSON object who's property keys are view types and values are arrays of the file types to assign to that view.");
let exampleText = document.createElement("div");
exampleText.style.fontSize = "80%";
exampleText.style.margin = "10px";
exampleText.innerHTML = `<b>Ex</b>: <code>${example}</code>`;
this._config.nameEl.parentElement.appendChild(exampleText);
let configTextArea = new import_obsidian.TextAreaComponent(containerEl).setPlaceholder(example).setValue(JSON.stringify(this.plugin.settings.types, null, 2)).onChange(async (value) => {
let parsed = null;
let next = {
...this.plugin.settings
};
try {
parsed = JSON.parse(value);
next.configIsValid = true;
next.types = parsed;
} catch (e) {
next.configIsValid = false;
}
this._updateConfigValidity(configTextArea, this.plugin.settings.configIsValid, next.configIsValid);
await this.plugin.updateSettings(next);
this._updateErrors();
this._updateList();
this._updateProfile();
});
configTextArea.inputEl.style.width = "100%";
configTextArea.inputEl.style.height = "150px";
configTextArea.inputEl.style.minHeight = "100px";
this._mobileConfig = new import_obsidian.Setting(containerEl).setName("Mobile Specific Config").setDesc("If enabled: the config settings below will be used on mobile devices, and the above settings.").addToggle((toggle) => {
toggle.setValue(this.plugin.settings.mobileSettings.enabled).onChange(async (value) => {
let next = {
...this.plugin.settings,
mobileSettings: {
...this.plugin.settings.mobileSettings,
enabled: value
}
};
await this.plugin.updateSettings(next);
this._updateMobileConfigVisible(mobileConfigField, value);
this._updateErrors();
this._updateList();
this._updateProfile();
});
return toggle;
});
let mobileConfigField = new import_obsidian.TextAreaComponent(containerEl).setPlaceholder(example).setValue(this.plugin.settings.mobileSettings.types ? JSON.stringify(this.plugin.settings.mobileSettings.types, null, 2) : "").onChange(async (value) => {
let next = {
...this.plugin.settings,
mobileSettings: {
...this.plugin.settings.mobileSettings,
types: void 0
}
};
if (value !== "" && value !== null && value !== void 0) {
try {
let parsed = JSON.parse(value);
next.mobileSettings.configIsValid = true;
next.mobileSettings.types = parsed;
} catch (e) {
next.mobileSettings.configIsValid = false;
}
}
this._updateConfigValidity(mobileConfigField, this.plugin.settings.mobileSettings.configIsValid, next.mobileSettings.configIsValid);
await this.plugin.updateSettings(next);
this._updateErrors();
this._updateList();
this._updateProfile();
});
mobileConfigField.inputEl.style.width = "100%";
mobileConfigField.inputEl.style.height = "150px";
mobileConfigField.inputEl.style.minHeight = "100px";
this._updateMobileConfigVisible(mobileConfigField, this.plugin.settings.mobileSettings.enabled);
new import_obsidian.Setting(containerEl).setName("Allow Override Of .md Extension").setDesc("If enabled: the .md extension will be allowed to override the default markdown view type. This is disabled by default to prevent unexpected behavior.").addToggle((toggle) => {
toggle.setValue(this.plugin.settings.allowMdOverride).onChange(async (value) => {
let next = {
...this.plugin.settings,
allowMdOverride: value
};
await this.plugin.updateSettings(next);
});
return toggle;
});
containerEl.createEl("h3", { text: "Errors" });
this._errors = containerEl.createEl("p", { text: "None" });
this._errors.style.whiteSpace = "pre-line";
containerEl.createEl("h3", { text: "Active View Types and Extensions" });
this._views = containerEl.createEl("p");
this._views.style.whiteSpace = "pre-line";
this._updateErrors();
this._updateList();
this._updateProfile();
}
_updateMobileConfigVisible(mobileConfigField, mobileSettingsEnabled) {
mobileConfigField.inputEl.style.display = mobileSettingsEnabled ? "block" : "none";
}
_updateConfigValidity(text, prevWasValid, nextIsValid) {
if (prevWasValid !== nextIsValid) {
if (prevWasValid) {
if (!this._defaults) {
this._defaults = {
color: text.inputEl.style.color,
borderColor: text.inputEl.style.borderColor,
borderWidth: text.inputEl.style.borderWidth
};
}
text.inputEl.style.color = "var(--text-error)";
text.inputEl.style.borderColor = "var(--background-modifier-error-rgb)";
text.inputEl.style.borderWidth = "3px";
} else if (this._defaults) {
text.inputEl.style.color = this._defaults.color;
text.inputEl.style.borderColor = this._defaults.borderColor;
text.inputEl.style.borderWidth = this._defaults.borderWidth;
}
}
}
_updateErrors() {
if (Object.keys(this.plugin.settings.errors).length === 0) {
this._errors.innerHTML = `None`;
this._errors.style.color = "green";
} else {
this._errors.innerHTML = `Errors: <ul>${Object.keys(this.plugin.settings.errors).map((k) => `<li><b>${k}</b>: ${this.plugin.settings.errors[k]}</li>`).join("")}</ul>`;
this._errors.style.color = "var(--text-error)";
}
}
_updateProfile() {
if (this.plugin.useMobile) {
this._mobileConfig.nameEl.innerHTML = `Mobile Specific Config&nbsp;<sup style="color: green">(active)</sup>`;
this._config.nameEl.innerHTML = `Config&nbsp;<sup style="color: gray">(inactive)</sup>`;
} else {
this._config.nameEl.innerHTML = `Config&nbsp;<sup style="color: green">(active)</sup>`;
this._mobileConfig.nameEl.innerHTML = `Mobile Specific Config&nbsp;<sup style="color: gray">(inactive)</sup>`;
}
}
_updateList() {
this._views.innerHTML = `<ul>${Object.keys(this.app.viewRegistry.viewByType).sort((a, b) => {
let extCountForViewKeyA = this._getExtensionsForView(a).length;
let extCountForViewKeyB = this._getExtensionsForView(b).length;
return extCountForViewKeyB - extCountForViewKeyA;
}).map((viewType) => {
const extensions = this._getExtensionsForView(viewType);
return `<li>${extensions.length > 0 ? `<b ${_copy()}>${viewType}</b>` : `<span ${_copy()} style="color: gray">${viewType}</span>`}${extensions.length ? `: ${extensions.sort((a, b) => b.length - a.length).map((ext) => ext ? `<code ${_copy()}>${ext}</code>` : `<code>""</code> <span style="color: gray"><i>(extensionless)</i></span>`).join(", ")}` : ``}</li>`;
}).join("")}</ul>`;
function _copy() {
return `
onmouseover="this.style.textDecoration='underline';"
onmouseout="this.style.textDecoration='none';"
title="Click to copy"
onclick="
navigator.clipboard.writeText(this.innerText);
new Notification('Custom File Extensions Plugin', {body:'Copied: \\'' + this.innerText + '\\', to clipboard.'});
"`;
}
}
_getExtensionsForView(view) {
return Object.entries(this.app.viewRegistry.typeByExtension).filter(([, v]) => v === view).map(([ext, _]) => ext);
}
};
// src/edit-modal.ts
var import_obsidian2 = require("obsidian");
var EditExtensionModal = class extends import_obsidian2.Modal {
constructor(plugin, target) {
var _a;
super(plugin.app);
this.plugin = plugin;
this.target = target;
(_a = this.target) != null ? _a : this.target = this.plugin.app.vault.getRoot();
this._path = this.target.path.split("/").slice(0, -1).join("/");
let lastPart = this.target.path.split("/").last();
this._name = lastPart.split(".")[0];
let lastParts = lastPart == null ? void 0 : lastPart.split(".");
this._originalExtension = this._newExtension = lastParts.length == 1 ? "" : lastParts.last();
}
onOpen() {
const { contentEl } = this;
contentEl.style.display = "flex";
contentEl.style.flexDirection = "column";
contentEl.style.alignItems = "center";
const fileNameDisplay = contentEl.createEl("span");
fileNameDisplay.style.flexGrow = "1";
fileNameDisplay.style.marginRight = "10px";
fileNameDisplay.style.fontWeight = "bold";
fileNameDisplay.style.textAlign = "center";
fileNameDisplay.innerHTML = this._buildFullPath();
const formDiv = contentEl.createEl("div");
formDiv.style.display = "flex";
formDiv.style.alignItems = "center";
const fileNameInput = new import_obsidian2.TextComponent(formDiv);
fileNameInput.inputEl.style.flexGrow = "1";
fileNameInput.inputEl.style.marginRight = "10px";
fileNameInput.setValue(this._originalExtension);
fileNameInput.inputEl.addEventListener("keypress", (e) => {
if (e.key === "Enter") {
this._submit();
} else if (e.key === "Escape") {
this.close();
}
});
fileNameInput.onChange((value) => {
this._newExtension = value.startsWith(".") ? value.slice(1) : value;
fileNameDisplay.innerHTML = this._buildFullPath();
});
const submitButton = new import_obsidian2.ButtonComponent(formDiv);
submitButton.setCta();
submitButton.setButtonText("Rename");
submitButton.onClick(() => this._submit());
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
async _submit() {
this.close();
let newPath = this._buildFullPath();
await this.app.vault.rename(this.target, newPath);
}
_buildFullPath() {
return this._path + "/" + this._name + (!!this._newExtension ? "." : "") + this._newExtension;
}
};
var edit_modal_default = EditExtensionModal;
// src/main.ts
var CustomFileExtensions = class extends import_obsidian3.Plugin {
get settings() {
return this._settings;
}
get useMobile() {
return import_obsidian3.Platform.isMobile && this.settings.mobileSettings.enabled;
}
async onload() {
super.onload();
await this.loadSettings();
if (this._settings.allowMdOverride) {
this.app.viewRegistry.unregisterExtensions(["md"]);
}
this.registerEvent(this._buildFileContextMenuEditExtensionItem());
this.addSettingTab(new CustomFileExtensionsSettingTab(this.app, this));
this._apply();
}
_buildFileContextMenuEditExtensionItem() {
return this.app.workspace.on("file-menu", (menu, file) => {
menu.addItem((item) => {
item.setTitle("Edit Extension").setIcon("pencil").onClick(() => new edit_modal_default(this, file).open());
});
});
}
onunload() {
this._unapply(this.settings);
try {
this.registerExtensions([".md"], "markdown");
} catch (e) {
}
}
async loadSettings() {
this._settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async resetSettings() {
this._unapply(this.settings);
await this.updateSettings(DEFAULT_SETTINGS);
this._apply();
}
async updateSettings(newSettings) {
this._unapply(newSettings);
this._settings = newSettings;
await this.saveData(this.settings);
this._apply();
}
_apply() {
var _a;
if (this.useMobile) {
this._applyConfig((_a = this.settings.mobileSettings.types) != null ? _a : this.settings.types);
} else {
this._applyConfig(this.settings.types);
}
}
_tryToApply(fileType, view) {
if (!this.settings.allowMdOverride && fileType === "md") {
return;
}
try {
this.registerExtensions([fileType], view);
} catch (e) {
let current = this.app.viewRegistry.getTypeByExtension(fileType);
let message;
if (current) {
message = `${fileType} is already registered to ${current}.`;
} else {
message = `${e}`;
}
message = `Could not register extension: '${fileType}' to view type: ${view}. ${message}`;
new Notification("Error: Custom File Extensions Plugin", {
body: message
});
console.error(message);
this._settings.errors[fileType] = message;
}
}
_applyConfig(extensionsByViewType) {
this._settings.errors = {};
for (const view in extensionsByViewType) {
for (const fileType of extensionsByViewType[view]) {
this._tryToApply(fileType.toLowerCase(), view);
}
}
}
_unapply(newSettings) {
var _a;
if (this.useMobile) {
this._unapplyConfig((_a = this.settings.mobileSettings.types) != null ? _a : this.settings.types, newSettings.allowMdOverride);
} else {
this._unapplyConfig(this.settings.types, newSettings.allowMdOverride);
}
}
_unapplyConfig(extensionsByViewType, allowMdOverride) {
for (const extension of Object.values(extensionsByViewType).flat()) {
if (allowMdOverride || extension !== "md") {
if (!this._settings.errors[extension]) {
try {
this.app.viewRegistry.unregisterExtensions([extension]);
} catch (e) {
const message = `Could not unregister extension: '${extension}'`;
new Notification("Error: Custom File Extensions Plugin", {
body: message
});
console.error(message);
}
}
}
}
}
};
var main_default = CustomFileExtensions;
/* nosourcemap */

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-custom-file-extensions-plugin",
"name": "Custom File Extensions Plugin",
"version": "1.2.1",
"minAppVersion": "0.10.12",
"description": "Associate views with custom file extensions via settings.",
"author": "Meep.Tech",
"authorUrl": "https://github.com/Meep-Tech/",
"isDesktopOnly": false
}

View file

@ -0,0 +1,67 @@
{
"commitMessage": "vault backup: {{date}}",
"autoCommitMessage": "vault backup: {{date}}",
"commitMessageScript": "",
"commitDateFormat": "YYYY-MM-DD HH:mm:ss",
"autoSaveInterval": 15,
"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": "rebase",
"mergeStrategy": "none",
"customMessageOnAutoBackup": false,
"autoBackupAfterFileChange": true,
"treeStructure": false,
"refreshSourceControl": true,
"basePath": "",
"differentIntervalCommitAndPush": false,
"changedFilesInStatusBar": true,
"showedMobileNotice": true,
"refreshSourceControlTimer": 7000,
"showBranchStatusBar": true,
"setLastSaveToLastCommit": false,
"submoduleRecurseCheckout": false,
"gitDir": "",
"showFileMenu": true,
"authorInHistoryView": "full",
"dateInHistoryView": true,
"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,
"lastShownAuthorDisplay": "initials",
"lastShownDateTimeFormatOptions": "date"
}
}

415
.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.38.3"
}

View file

@ -0,0 +1,705 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.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%;
}
/* Re-enable wrapping of nav buttns to prevent overflow on smaller screens #*/
.workspace-drawer .git-view .nav-buttons-container {
flex-wrap: wrap;
}
.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;
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: #cc3333;
--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;
}
/* My additions */
.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;
}
}
/* ====================== 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;
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;
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;
/* Needed to align the sign properly for different line heigts. Such as
* when having a heading or list item.
*/
padding-top: 0 !important;
}
}
.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;
}
/* 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

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,11 @@
{
"id": "obsidian-latex-suite",
"name": "Latex Suite",
"version": "1.11.5",
"minAppVersion": "1.0.0",
"description": "Make typesetting LaTeX math as fast as handwriting through snippets, text expansion, and editor enhancements",
"author": "artisticat",
"authorUrl": "https://github.com/artisticat1",
"fundingUrl": "https://ko-fi.com/artisticat",
"isDesktopOnly": false
}

View file

@ -0,0 +1,264 @@
/* Settings panel */
.setting-item.hidden {
display: none;
}
.setting-item.setting-item-heading .latex-suite-settings-icon {
margin-right: var(--size-4-2);
display: inline-flex;
}
.setting-item.setting-item-heading:has(.latex-suite-settings-icon) {
border-bottom: 1px solid var(--background-modifier-border);
}
.setting-item.setting-item-heading:has(.latex-suite-settings-icon) + .setting-item {
border-top: none;
}
.setting-item.setting-item-heading:has(.latex-suite-settings-icon) ~ .setting-item:not(.setting-item-heading), .latex-suite-snippet-variables-setting + .setting-item-control {
width: calc(100% - 26px);
margin-left: 26px;
}
.latex-suite-snippet-variables-setting .setting-item-control {
height: 120px;
}
.latex-suite-snippet-variables-setting .setting-item-control textarea {
width: 100%;
height: 100%;
}
.snippets-text-area, .latex-suite-snippet-variables-setting {
display: inline-block;
}
.snippets-text-area .setting-item-info, .latex-suite-snippet-variables-setting .setting-item-info {
margin-bottom: 0.75rem;
}
.snippets-text-area .setting-item-control {
flex-direction: column;
align-items: flex-end;
}
.snippets-editor-wrapper {
width: 100%;
margin-bottom: 0.75rem;
}
.snippets-editor-wrapper .cm-editor {
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
font-size: var(--font-inputs);
height: 20em;
outline: none !important;
text-align: left;
}
.snippets-editor-wrapper .cm-line, .snippets-editor-wrapper .cm-lineNumbers {
font-family: var(--font-monospace);
}
.snippets-footer {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.snippets-editor-validity {
display: flex;
align-items: center;
}
.snippets-editor-validity-indicator {
color: white;
display: inline-block;
border-radius: 1em;
margin-right: 10px;
cursor: default;
visibility: hidden;
}
.snippets-editor-validity-indicator svg {
width: 16px !important;
height: 16px !important;
}
.snippets-editor-validity-indicator:hover {
color: white;
}
.snippets-editor-validity-indicator.valid {
background-color: var(--color-green);
visibility: visible;
}
.snippets-editor-validity-indicator.invalid {
background-color: var(--color-red);
visibility: visible;
}
.snippets-editor-buttons {
display: flex;
flex-direction: row;
}
.latex-suite-confirmation-modal .setting-item {
border: none;
}
.search-input-container input.latex-suite-location-input-el {
width: initial;
}
/*
Snippet color classes.
*/
/* These extra selectors enforce their color on all children, because CodeMirror does weird nesting of spans when
nesting multiple decorations. */
.latex-suite-snippet-placeholder {
border-radius: 2px;
background-color: var(--placeholder-bg);
outline: var(--placeholder-outline) solid 1px;
}
.latex-suite-snippet-placeholder-0, span.latex-suite-snippet-placeholder-0 span {
--placeholder-bg: #87cefa2e;
--placeholder-outline: #87cefa6e;
}
.theme-dark .latex-suite-snippet-placeholder-0, span.latex-suite-snippet-placeholder-0 span {
--placeholder-outline: #87cefa43;
}
.latex-suite-snippet-placeholder-1, span.latex-suite-snippet-placeholder-1 span {
--placeholder-bg: #ffa50033;
--placeholder-outline: #ffa5006b;
}
.theme-dark .latex-suite-snippet-placeholder-1, span.latex-suite-snippet-placeholder-1 span {
--placeholder-outline: #ffa5004d;
}
.latex-suite-snippet-placeholder-2, span.latex-suite-snippet-placeholder-2 span {
--placeholder-bg: #00ff0022;
--placeholder-outline: #00ff0060;
}
.theme-dark .latex-suite-snippet-placeholder-2, span.latex-suite-snippet-placeholder-2 span {
--placeholder-outline: #00ff003d;
}
/* Conceal */
span.cm-math.cm-concealed-bold {
font-weight: bold;
}
span.cm-math.cm-concealed-underline {
text-decoration: underline;
}
span.cm-math.cm-concealed-mathrm, sub.cm-math.cm-concealed-mathrm {
font-style: normal;
}
/* Conceal superscripts without changing line height */
sup.cm-math {
line-height: 0;
}
sup.cm-math, sub.cm-math {
font-style: italic;
}
/* Inline math tooltip styling */
.theme-light .cm-tooltip.cm-tooltip-cursor {
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.028), 0px 3.4px 6.7px rgba(0, 0, 0, .042), 0px 5px 20px rgba(0, 0, 0, .07);
}
.theme-dark .cm-tooltip.cm-tooltip-cursor {
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1),
0px 3.4px 6.7px rgba(0, 0, 0, 0.15),
0px 0px 30px rgba(0, 0, 0, 0.27);
}
/* CM6 puts the top of the tooltip higher than what's viewable (negative top value),
so to compensate for this, we align the content to the bottom of the tooltip container,
and limit the height.
*/
.cm-tooltip.cm-tooltip-cursor.cm-tooltip-above {
display: flex;
}
.cm-tooltip.cm-tooltip-cursor.cm-tooltip-above > .MathJax {
overflow-y: auto;
max-height: 70%;
display: inline-block;
align-self: flex-end;
}
.cm-tooltip.cm-tooltip-cursor.cm-tooltip-below > .MathJax {
overflow-y: auto;
max-height: 90%;
}
/* Highlight brackets */
.theme-light .latex-suite-highlighted-bracket, .theme-light .latex-suite-highlighted-bracket [class^="latex-suite-color-bracket-"] {
background-color: hsl(var(--accent-h), var(--accent-s), 40%, 0.3);
}
.theme-dark .latex-suite-highlighted-bracket, .theme-dark .latex-suite-highlighted-bracket [class^="latex-suite-color-bracket-"] {
background-color: hsl(var(--accent-h), var(--accent-s), 70%, 0.6);
}
/* Color matching brackets */
.theme-light .latex-suite-color-bracket-0, .theme-light .latex-suite-color-bracket-0 .cm-bracket {
color: #527aff;
}
.theme-dark .latex-suite-color-bracket-0, .theme-dark .latex-suite-color-bracket-0 .cm-bracket {
color: #47b8ff;
}
.theme-light .latex-suite-color-bracket-1, .theme-light .latex-suite-color-bracket-1 .cm-bracket {
color: #ff50b7;
}
.theme-dark .latex-suite-color-bracket-1, .theme-dark .latex-suite-color-bracket-1 .cm-bracket {
color: #ff55cd;
}
.theme-light .latex-suite-color-bracket-2, .theme-light .latex-suite-color-bracket-2 .cm-bracket {
color: #69ba00;
}
.theme-dark .latex-suite-color-bracket-2, .theme-dark .latex-suite-color-bracket-2 .cm-bracket {
color: #73ff63;
}
/* .latex-suite-color-bracket-3 {
color: #8de15c;
} */
.latex-suite-math-preview-highlight {
background-color: var(--text-selection);
}
.cm-snippetFieldPosition {
vertical-align: text-top;
width: 0;
height: 1.15em;
display: inline-block;
margin: 0 -0.7px -.7em;
border-left: 1.4px dotted #888;
}

View file

@ -0,0 +1,303 @@
{
"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": false,
"alias-key": true,
"tag-key": true,
"default-array-style": "single-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": "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": 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-created-source-of-truth": "file system",
"date-modified": true,
"date-modified-key": "date modified",
"date-modified-source-of-truth": "file system",
"format": "dddd, MMMM Do YYYY, h:mm:ss a",
"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, 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": true
},
"remove-trailing-punctuation-in-heading": {
"enabled": false,
"punctuation-to-remove": ".,;:!。,;:!"
},
"footnote-after-punctuation": {
"enabled": true
},
"move-footnotes-to-the-bottom": {
"enabled": true,
"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": false
},
"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": true
},
"quote-style": {
"enabled": false,
"single-quote-enabled": true,
"single-quote-style": "''",
"double-quote-enabled": true,
"double-quote-style": "\"\""
},
"remove-consecutive-list-markers": {
"enabled": true
},
"remove-empty-list-markers": {
"enabled": true
},
"remove-hyphenated-line-breaks": {
"enabled": false
},
"remove-multiple-spaces": {
"enabled": true
},
"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": true
},
"empty-line-around-code-fences": {
"enabled": true
},
"empty-line-around-horizontal-rules": {
"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": 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": true,
"displayLintOnFileChangeNotice": false,
"settingsConvertedToConfigKeyValues": true,
"additionalFileExtensions": [
"qmd"
],
"foldersToIgnore": [],
"filesToIgnore": [
{
"match": "^Meta/Modèles/ZI_Template\\.md$",
"flags": "",
"label": ""
}
],
"linterLocale": "system-default",
"logLevel": "ERROR",
"lintCommands": [],
"customRegexes": [],
"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.2",
"minAppVersion": "1.12.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}

View file

@ -0,0 +1,171 @@
{
"remoteType": "",
"useCustomRequestHandler": false,
"couchDB_URI": "",
"couchDB_USER": "",
"couchDB_PASSWORD": "",
"couchDB_DBNAME": "",
"liveSync": true,
"syncOnSave": false,
"syncOnStart": false,
"savingDelay": 200,
"lessInformationInLog": false,
"gcDelay": 0,
"versionUpFlash": "",
"minimumChunkSize": 20,
"longLineThreshold": 250,
"showVerboseLog": false,
"suspendFileWatching": false,
"trashInsteadDelete": true,
"periodicReplication": false,
"periodicReplicationInterval": 60,
"syncOnFileOpen": false,
"encrypt": true,
"passphrase": "",
"usePathObfuscation": true,
"doNotDeleteFolder": false,
"resolveConflictsByNewerFile": false,
"batchSave": false,
"batchSaveMinimumDelay": 5,
"batchSaveMaximumDelay": 60,
"deviceAndVaultName": "",
"usePluginSettings": false,
"showOwnPlugins": false,
"showStatusOnEditor": true,
"showStatusOnStatusbar": true,
"showOnlyIconsOnEditor": false,
"hideFileWarningNotice": false,
"networkWarningStyle": "",
"usePluginSync": false,
"autoSweepPlugins": false,
"autoSweepPluginsPeriodic": false,
"notifyPluginOrSettingUpdated": false,
"checkIntegrityOnSave": false,
"batch_size": 25,
"batches_limit": 25,
"useHistory": true,
"disableRequestURI": true,
"skipOlderFilesOnSync": true,
"checkConflictOnlyOnOpen": false,
"showMergeDialogOnlyOnActive": false,
"syncInternalFiles": false,
"syncInternalFilesBeforeReplication": false,
"syncInternalFilesIgnorePatterns": "\\/node_modules\\/, \\/\\.git\\/, \\/obsidian-livesync\\/",
"syncInternalFilesTargetPatterns": "",
"syncInternalFilesInterval": 60,
"additionalSuffixOfDatabaseName": "949e3f3f8b9f8e9a",
"ignoreVersionCheck": false,
"lastReadUpdates": 25,
"deleteMetadataOfDeletedFiles": false,
"syncIgnoreRegEx": "",
"syncOnlyRegEx": "",
"customChunkSize": 0,
"readChunksOnline": true,
"watchInternalFileChanges": true,
"automaticallyDeleteMetadataOfDeletedFiles": 0,
"disableMarkdownAutoMerge": false,
"writeDocumentsIfConflicted": false,
"useDynamicIterationCount": false,
"syncAfterMerge": false,
"configPassphraseStore": "",
"encryptedPassphrase": "%$U76C/u2KmZ3FQ2VmzCSL1RK0VGHAL4znd0s5ihlDPC8qci/TAWBoNFN/TfO9qS6VPbFn3ApeXJbMnbF9SBg7evaeN6N+INEhxQ6VbfBFA/Bw8dt3jpnE+ENBSi8mpXlN4Q1DdEGdvDhl738BGqk=",
"encryptedCouchDBConnection": "%$U76C/u2KmZ3FQ2VmzCSL1RK0VGHAL4znd0s5ihlDPC9mTlDIJJIZterqlk1cN924HTCpdLlSyAqEs6D9Vfzpuncs5kklcHT1FlNH9iEd73iZFUq7Kgp6NIFt3s5hirra6gvhihoe7c79BgMUGJmnmiZOAT8mYB6JivqZEnw7KxN6HIIcTGYJiJmTFgRh2ZEbdIMSOhHzicJVhSjUie+n4rlIzPrXxiqIEhiUyJFpuCiaCINUQlFz10owrml9UpjUa2jfu9gYg6OQjIVpKPRpgsizyBb0C+gP7ikmq0awAaxWDAvKLZGjJmFFFqd4QQcorinCd5itaJUtSiNFaBbOfuTiO/dV0TSNAt4TMnk/6MVGkAwQPA3KjeE/Vp9nvn2O6aenVk1Elsb9CpiNp0EYqrh5Yo5va0MlyfJZULWvzFjbB4XuQxMVmD5lFzvCGJ6QU7i5sMKrZi0qJU3YnsZ5TeyreLgPI5/tPUkwmPYqDGRh7FfJXOhtMdFwSix+10qrus7k9elY0pCVBtG8mCAp0In8wmyaAZ3NyYJMnT7+DtCHmYnFT+IERgP1P9Uf8Ecp5FSJWrFLkX43bsA1N01LX2ofL3dQoEbtB2JB6yLGfLmjyxo2JUT7q5IhWxRgdsmerc5Ze+wreLQwUuRiVxSStSzhoBd8ExzCXDAurzODcYY9WJp/tvnvMlTAWD1HnTEl0T5jWaHNnvgSv25DoLfVwfuumkmtpBs2NnEoNMiCpowdYOTu9wNNqJ/uNyU=",
"permitEmptyPassphrase": false,
"remoteConfigurations": {
"legacy-couchdb": {
"id": "legacy-couchdb",
"name": "CouchDB Remote",
"uri": "%$U76C/u2KmZ3FQ2VmzCSL1RK0VGHAL4znd0s5ihlDPC+sYELhS5zOuRx1QewULyFpDRLiGjOF/tA5YtckKZopgwD9WKP8UgqefQ4S+VgURG24fm7cbfB9zNiPsNTUJjHX8j7+62Osr8b0DcmiQxOHhxL2L7x7GDGdFMrZJg28wkP1QOAxV6CgI1z5g3OJomVDajCFJxEmajDG0WuWPkY/hd9b5MsB2FU3H3aAU11FafMSvBTcG8PiSbBuXuFRmq50sbpXNV8pMQ==",
"isEncrypted": true
}
},
"activeConfigurationId": "legacy-couchdb",
"P2P_ActiveRemoteConfigurationId": "",
"useIndexedDBAdapter": false,
"useTimeouts": false,
"writeLogToTheFile": false,
"doNotPaceReplication": false,
"hashCacheMaxCount": 300,
"hashCacheMaxAmount": 50,
"concurrencyOfReadChunksOnline": 40,
"minimumIntervalOfReadChunksOnline": 50,
"hashAlg": "xxhash64",
"suspendParseReplicationResult": false,
"doNotSuspendOnFetching": false,
"useIgnoreFiles": false,
"ignoreFiles": ".gitignore",
"syncOnEditorSave": false,
"pluginSyncExtendedSetting": {},
"syncMaxSizeInMB": 50,
"settingSyncFile": "",
"writeCredentialsForSettingSync": false,
"notifyAllSettingSyncFile": false,
"isConfigured": true,
"settingVersion": 10,
"enableCompression": false,
"accessKey": "",
"bucket": "",
"endpoint": "",
"region": "",
"secretKey": "",
"useEden": false,
"maxChunksInEden": 10,
"maxTotalLengthInEden": 1024,
"maxAgeInEden": 10,
"disableCheckingConfigMismatch": false,
"displayLanguage": "fr",
"enableChunkSplitterV2": false,
"disableWorkerForGeneratingChunks": false,
"processSmallFilesInUIThread": false,
"notifyThresholdOfRemoteStorageSize": 0,
"usePluginSyncV2": false,
"usePluginEtc": false,
"doNotUseFixedRevisionForChunks": true,
"showLongerLogInsideEditor": false,
"sendChunksBulk": false,
"sendChunksBulkMaxSize": 1,
"useSegmenter": false,
"useAdvancedMode": false,
"usePowerUserMode": false,
"useEdgeCaseMode": false,
"enableDebugTools": false,
"suppressNotifyHiddenFilesChange": false,
"syncMinimumInterval": 2000,
"P2P_Enabled": false,
"P2P_AutoAccepting": 0,
"P2P_AppID": "self-hosted-livesync",
"P2P_roomID": "",
"P2P_passphrase": "",
"P2P_relays": "wss://exp-relay.vrtmrz.net/",
"P2P_AutoBroadcast": false,
"P2P_AutoStart": false,
"P2P_AutoSyncPeers": "",
"P2P_AutoWatchPeers": "",
"P2P_SyncOnReplication": "",
"P2P_RebuildFrom": "",
"P2P_AutoAcceptingPeers": "",
"P2P_AutoDenyingPeers": "",
"P2P_IsHeadless": false,
"P2P_DevicePeerName": "",
"P2P_turnServers": "",
"P2P_turnUsername": "",
"P2P_turnCredential": "",
"doctorProcessedVersion": "0.25.27",
"bucketCustomHeaders": "",
"couchDB_CustomHeaders": "",
"useJWT": false,
"jwtAlgorithm": "",
"jwtKey": "",
"jwtKid": "",
"jwtSub": "",
"jwtExpDuration": 5,
"useRequestAPI": false,
"bucketPrefix": "",
"chunkSplitterVersion": "v3-rabin-karp",
"E2EEAlgorithm": "v2",
"processSizeMismatchedFiles": false,
"forcePathStyle": true,
"syncInternalFileOverwritePatterns": "",
"useOnlyLocalChunk": false,
"maxMTimeForReflectEvents": 0
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-livesync",
"name": "Self-hosted LiveSync",
"version": "0.25.74",
"minAppVersion": "1.7.2",
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"author": "vorotamoroz",
"authorUrl": "https://github.com/vrtmrz",
"isDesktopOnly": false
}

View file

@ -0,0 +1,573 @@
.ls-dialog .added {
color: var(--text-on-accent);
background-color: var(--text-accent);
}
.ls-dialog .normal {
color: var(--text-normal);
}
.ls-dialog .deleted {
color: var(--text-on-accent);
background-color: var(--text-muted);
}
.conflict-dev-name {
display: inline-block;
min-width: 5em;
}
.conflict-action-button {
margin-right: 4px;
}
.op-scrollable {
overflow-y: scroll;
/* min-height: 280px; */
max-height: 280px;
user-select: text;
-webkit-user-select: text;
}
.op-pre {
white-space: pre-wrap;
}
.op-warn {
border: 1px solid salmon;
padding: 2px;
border-radius: 4px;
}
.op-warn::before {
content: "Warning";
font-weight: bold;
color: salmon;
position: relative;
display: block;
}
.op-warn-info {
border: 1px solid rgb(255, 209, 81);
padding: 2px;
border-radius: 4px;
}
.op-warn-info::before {
content: "Notice";
font-weight: bold;
color: rgb(255, 209, 81);
position: relative;
display: block;
}
.syncstatusbar {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.tcenter {
text-align: center;
}
.sls-plugins-wrap {
display: flex;
flex-grow: 1;
max-height: 50vh;
overflow-y: scroll;
}
.sls-remote-list .setting-item-description {
white-space: normal;
overflow-wrap: anywhere;
word-break: break-word;
}
.sls-plugins-tbl {
border: 1px solid var(--background-modifier-border);
width: 100%;
max-height: 80%;
}
.divider th {
border-top: 1px solid var(--background-modifier-border);
}
.sls-header-button {
margin-left: 2em;
}
.sls-hidden {
display: none;
}
:root {
--sls-log-text: "";
}
.sls-troubleshoot-preview {
max-width: max-content;
}
.sls-troubleshoot-preview img {
max-width: 100%;
}
.sls-setting-tab {
display: none;
}
div.sls-setting-menu-btn {
color: var(--text-normal);
background-color: var(--background-secondary-alt);
border-radius: 8px;
padding: 6px 10px;
cursor: pointer;
margin-right: 2px;
font-family: "Inter", sans-serif;
outline: none;
user-select: none;
flex-grow: 1;
text-align: center;
flex-shrink: 1;
}
.sls-setting-label.selected {
/* order: 1; */
flex-grow: 1;
/* width: 100%; */
}
.sls-setting-tab:hover~div.sls-setting-menu-btn,
.sls-setting-label.selected .sls-setting-tab:checked~div.sls-setting-menu-btn {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.sls-setting-menu-wrapper {
display: flex;
flex-direction: column;
flex-grow: 1;
position: sticky;
top: 0;
backdrop-filter: blur(15px);
padding: 4px;
border-radius: 10px;
z-index: 10;
}
.sls-setting-menu {
display: flex;
flex-direction: row;
overflow-x: auto;
}
body {
--sls-col-transparent: transparent;
--sls-col-warn: rgba(var(--background-modifier-error-rgb), 0.1);
--sls-col-warn-stripe1: var(--sls-col-transparent);
--sls-col-warn-stripe2: var(--sls-col-warn);
}
.sls-setting-menu-buttons {
border: 1px solid var(--sls-col-warn);
/* padding: 2px; */
margin: 1px;
border-radius: 4px;
background-image: linear-gradient(-45deg,
var(--sls-col-warn-stripe1) 25%, var(--sls-col-warn-stripe2) 25%, var(--sls-col-warn-stripe2) 50%,
var(--sls-col-warn-stripe1) 50%, var(--sls-col-warn-stripe1) 75%, var(--sls-col-warn-stripe2) 75%, var(--sls-col-warn-stripe2));
background-size: 30px 30px;
display: flex;
flex-direction: row;
/* justify-content: flex-end; */
padding: 0.5em 0.25em;
justify-content: center;
align-items: center;
/* transition: background-position 1s; */
animation: sls-scroll-warn 1s linear 0s infinite;
}
@keyframes sls-scroll-warn {
0% {
background-position: 0 0;
}
100% {
background-position: 30px 0;
}
}
.sls-setting-menu-buttons label {
margin-right: auto;
flex-grow: 1;
color: var(--text-warning);
}
.sls-setting-label {
flex-grow: 1;
display: inline-flex;
justify-content: center;
}
.setting-collapsed {
display: none;
}
.sls-plugins-tbl-buttons {
text-align: right;
}
.sls-plugins-tbl-buttons button {
flex-grow: 0;
padding: 6px 10px;
}
.sls-plugins-tbl-device-head {
background-color: var(--background-secondary-alt);
color: var(--text-accent);
}
.op-flex {
display: flex;
}
.op-flex input {
display: inline-flex;
flex-grow: 1;
margin-bottom: 8px;
}
.op-info {
display: inline-flex;
flex-grow: 1;
border-bottom: 1px solid var(--background-modifier-border);
width: 100%;
margin-bottom: 4px;
padding-bottom: 4px;
}
.history-added {
color: var(--text-on-accent);
background-color: var(--text-accent);
}
.history-normal {
color: var(--text-normal);
}
.history-deleted {
color: var(--text-on-accent);
background-color: var(--text-muted);
text-decoration: line-through;
}
.ob-btn-config-fix label {
margin-right: 40px;
}
.ob-btn-config-info {
border: 1px solid salmon;
padding: 2px;
margin: 1px;
border-radius: 4px;
}
.ob-btn-config-head {
padding: 2px;
margin: 1px;
border-radius: 4px;
}
.isWizard .wizardHidden {
display: none;
}
.sls-setting:not(.isWizard) .wizardOnly {
display: none;
}
.sls-item-dirty::before {
content: "✏";
}
.sls-item-dirty-help::after {
content: " ❓";
}
.sls-setting .setting-item-control input.sls-item-invalid-value,
.sls-setting .setting-item-control textarea.sls-item-invalid-value {
background-color: rgba(var(--background-modifier-error-rgb), 0.3);
}
.sls-setting-disabled input[type=text],
.sls-setting-disabled input[type=number],
.sls-setting-disabled input[type=password] {
filter: brightness(80%);
color: var(--text-muted);
}
.sls-setting-hidden {
display: none;
}
.sls-setting-obsolete {
/* background-image: linear-gradient(-45deg,
var(--sls-col-warn-stripe1) 25%, var(--sls-col-warn-stripe2) 25%, var(--sls-col-warn-stripe2) 50%,
var(--sls-col-warn-stripe1) 50%, var(--sls-col-warn-stripe1) 75%, var(--sls-col-warn-stripe2) 75%, var(--sls-col-warn-stripe2)); */
background-image: linear-gradient(-45deg,
transparent 25%, rgba(var(--background-secondary), 0.1) 25%, rgba(var(--background-secondary), 0.1) 50%, transparent 50%, transparent 75%, rgba(var(--background-secondary), 0.1) 75%, rgba(var(--background-secondary), 0.1));
background-size: 60px 60px;
}
.password-input>.setting-item-control>input {
-webkit-text-security: disc;
}
span.ls-mark-cr::after {
user-select: none;
content: "↲";
color: var(--text-muted);
font-size: 0.8em;
}
.deleted span.ls-mark-cr::after {
color: var(--text-on-accent);
}
.ls-imgdiff-wrap {
display: flex;
justify-content: center;
align-items: center;
}
.ls-imgdiff-wrap .overlay {
position: relative;
}
.ls-imgdiff-wrap .overlay .img-base {
position: relative;
top: 0;
left: 0;
}
.ls-imgdiff-wrap .overlay .img-overlay {
-webkit-filter: invert(100%) opacity(50%);
filter: invert(100%) opacity(50%);
position: absolute;
top: 0;
left: 0;
animation: ls-blink-diff 0.5s cubic-bezier(0.4, 0, 1, 1) infinite alternate;
}
@keyframes ls-blink-diff {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.livesync-status {
user-select: none;
pointer-events: none;
height: auto;
min-height: 1em;
position: absolute;
background-color: transparent;
width: 100%;
padding: 10px;
padding-right: 16px;
top: var(--header-height);
z-index: calc(var(--layer-cover) + 1);
font-variant-numeric: tabular-nums;
tab-size: 4;
text-align: right;
white-space: pre-wrap;
display: inline-block;
color: var(--text-normal);
font-size: 80%;
}
div.workspace-leaf-content[data-type=bases] .livesync-status {
top: calc(var(--bases-header-height) + var(--header-height));
padding: 5px;
padding-right: 18px;
}
.is-mobile div.workspace-leaf-content[data-type=bases] .livesync-status {
top: calc(var(--bases-header-height) + var(--view-header-height));
padding: 6px;
padding-right: 18px;
}
.livesync-status div {
opacity: 0.6;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.livesync-status .livesync-status-loghistory {
text-align: left;
opacity: 0.4;
}
.livesync-status div.livesync-status-messagearea:empty {
display: none;
}
.livesync-status div.livesync-status-messagearea:not(:empty) {
opacity: 0.6;
color: var(--text-on-accent);
border: 1px solid var(--background-modifier-error);
background-color: rgba(var(--background-modifier-error-rgb), 0.2);
-webkit-filter: unset;
filter: unset;
width: fit-content;
margin-left: auto;
}
.menu-setting-poweruser-disabled .sls-setting-poweruser {
display: none;
}
.menu-setting-advanced-disabled .sls-setting-advanced {
display: none;
}
.menu-setting-edgecase-disabled .sls-setting-edgecase {
display: none;
}
.sls-setting-panel-title {
position: sticky;
font-size: medium;
top: 2.5em;
background-color: var(--background-secondary-alt);
border-radius: 10px;
padding: 0.5em 1.0em;
}
.active-pane .sls-setting-panel-title {
border: 1px solid var(--interactive-accent);
}
.sls-dialogue-note-wrapper {
display: flex;
justify-content: flex-end;
align-items: center;
}
.sls-dialogue-note-countdown {
font-size: 0.8em;
}
.sls-qr {
display: flex;
justify-content: center;
align-items: center;
max-width: max-content;
}
.sls-keypair pre {
max-width: 100%;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-all;
}
/* Diff navigation */
.diff-options-row {
display: flex;
align-items: center;
gap: 8px;
}
.diff-nav {
display: flex;
align-items: center;
gap: 4px;
margin-left: auto;
}
.diff-nav-btn {
padding: 2px 8px;
font-size: 0.85em;
cursor: pointer;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background-color: var(--background-secondary);
color: var(--text-normal);
}
.diff-nav-btn:hover {
background-color: var(--background-modifier-hover);
}
.diff-nav-indicator {
font-size: 0.85em;
color: var(--text-muted);
min-width: 3em;
text-align: center;
}
.diff-only-label {
margin-left: 10px;
}
.history-search-row {
display: flex;
gap: 5px;
align-items: center;
margin-bottom: 10px;
}
.history-search-input {
flex-grow: 1;
}
.history-search-result-indicator {
font-size: 0.8em;
min-width: 80px;
}
.history-search-progress-indicator {
font-size: 0.8em;
color: var(--text-muted);
}
.history-diff-options-row {
justify-content: space-between;
}
.history-highlight-diff-container,
.history-highlight-diff-label {
display: flex;
align-items: center;
}
.history-highlight-diff-label {
gap: 4px;
}
.diff-focused {
outline: 2px solid var(--interactive-accent);
outline-offset: 1px;
border-radius: 2px;
}

View file

@ -0,0 +1,31 @@
{
"pathToPandoc": "/usr/bin/pandoc",
"tooltipDelay": 400,
"zoteroGroups": [
{
"id": 1,
"name": "Ma bibliothèque",
"lastUpdate": 1779193594657
},
{
"id": 4,
"name": "HappyR ABC"
},
{
"id": 2,
"name": "MSV"
},
{
"id": 3,
"name": "Thèse Louis Lacoste"
}
],
"renderCitations": true,
"renderCitationsReadingMode": true,
"renderLinkCitations": true,
"pullFromZotero": false,
"pathToBibliography": "/home/louis/Documents/Obsidian/Louis/Thèse/these_ref.bib",
"cslStyleURL": "https://raw.githubusercontent.com/citation-style-language/styles/master/chicago-author-date.csl",
"enableCiteKeyCompletion": true,
"showCitekeyTooltips": true
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-pandoc-reference-list",
"name": "Pandoc Reference List",
"version": "2.0.25",
"minAppVersion": "0.15.0",
"description": "Displays a formatted reference in the sidebar for each pandoc citekey present in the current document.",
"author": "mgmeyers",
"authorUrl": "https://github.com/mgmeyers/obsidian-pandoc-reference-list",
"isDesktopOnly": true
}

View file

@ -0,0 +1,410 @@
/* @settings
name: Pandoc Reference List
id: pandoc-reference-list
settings:
-
id: pwc-font-size
title: Sidebar reference list font size
type: variable-number-slider
default: 14
format: px
min: 8
max: 24
step: 1
-
id: pwc-tooltip-font-size
title: Tooltip citation font size
type: variable-number-slider
default: 14
format: px
min: 8
max: 24
step: 1
-
id: pwc-citation-color
title: Citation color
type: variable-themed-color
format: hex
default-light: '#2e3338'
default-dark: '#dcddde'
-
id: pwc-citation-color-missing
title: Unresolved citation color
description: This color will be applied if a citekey is not found in your bibliography file
type: variable-themed-color
format: hex
default-light: '#2e3338'
default-dark: '#dcddde'
-
id: pwc-citation-underline-color
title: Citation underline color
type: variable-themed-color
format: hex
default-light: '#705dcf'
default-dark: '#7f6df2'
-
id: pwc-citation-underline-color-missing
title: Unresolved citation underline color
description: This color will be applied if a citekey is not found in your bibliography file
type: variable-themed-color
format: hex
default-light: '#'
default-dark: '#'
-
id: pwc-citation-formatting-color
title: Citation formatting color
description: Changes the color of brackets and semicolons
type: variable-themed-color
format: hex
default-light: '#2e3338'
default-dark: '#dcddde'
-
id: pwc-citation-extra-color
title: 'Citation "extra" color'
description: 'Changes the color text within a citation, eg. "pp. 22-24"'
type: variable-themed-color
format: hex
default-light: '#2e3338'
default-dark: '#dcddde'
*/
body {
--pwc-font-size: 14px;
--pwc-tooltip-font-size: 14px;
--pwc-citation-underline-color: var(--text-accent);
--pwc-citation-underline-color-missing: transparent;
--pwc-citation-extra-color: var(--text-normal);
--pwc-citation-formatting-color: var(--text-normal);
--pwc-citation-color: var(--text-normal);
--pwc-citation-color-missing: var(--text-normal);
}
.pwc-reference-list {
padding-bottom: 2rem;
}
.pwc-reference-list__title {
font-size: var(--pwc-font-size);
font-weight: bold;
padding: 0 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.pwc-reference-list__title > div {
display: flex;
align-items: center;
gap: var(--size-4-1);
}
.pwc-reference-list__count {
color: var(--text-muted);
display: flex;
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--tag-radius);
background-color: rgba(var(--mono-rgb-100), 0.05);
font-weight: var(--font-normal);
line-height: 1;
font-size: var(--font-ui-smaller);
}
.pwc-no-content {
font-size: var(--pwc-font-size);
padding: 0 5px;
color: var(--text-muted);
}
.csl-entry-wrapper {
--icon-size: var(--icon-s);
--icon-stroke: var(--icon-s-stroke-width);
display: flex;
padding: 1em 5px;
gap: var(--size-4-2);
}
.pwc-tooltip .csl-entry-wrapper {
padding: 0;
}
.csl-entry {
font-size: var(--pwc-font-size);
word-wrap: break-word;
gap: var(--size-4-2);
}
.csl-entry:has(> div + div) {
display: flex;
}
.pwc-reference-list .csl-entry-wrapper:not(:last-child) {
border-bottom: 1px solid var(--background-modifier-border);
}
.pwc-entry-btns {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.pwc-reference-list a.footnote-ref {
vertical-align: super;
}
.pwc-reference-list em,
.pwc-reference-list em em em,
.pwc-reference-list em em em em em {
font-style: italic;
}
.pwc-reference-list em em,
.pwc-reference-list em em em em {
font-style: normal;
}
.pwc-reference-list code {
white-space: pre-wrap;
}
.pwc-reference-list span.smallcaps {
font-variant: small-caps;
}
.pwc-reference-list span.underline {
text-decoration: underline;
}
.pwc-reference-list q {
quotes: '“' '”' '' '';
}
.pwc-reference-list div.column {
display: inline-block;
vertical-align: top;
width: 50%;
}
.pwc-tooltip.collapsed-links a,
.pwc-reference-list.collapsed-links a {
font-size: 0;
}
.pwc-tooltip.collapsed-links a::after,
.pwc-reference-list.collapsed-links a::after {
font-size: var(--pwc-font-size);
content: ' ';
display: inline-block;
width: 1em;
height: 1em;
background-color: var(--text-accent);
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath d='M8.465 11.293c1.133-1.133 3.109-1.133 4.242 0l.707.707 1.414-1.414-.707-.707c-.943-.944-2.199-1.465-3.535-1.465s-2.592.521-3.535 1.465L4.929 12a5.008 5.008 0 0 0 0 7.071 4.983 4.983 0 0 0 3.535 1.462A4.982 4.982 0 0 0 12 19.071l.707-.707-1.414-1.414-.707.707a3.007 3.007 0 0 1-4.243 0 3.005 3.005 0 0 1 0-4.243l2.122-2.121z'%3E%3C/path%3E%3Cpath d='m12 4.929-.707.707 1.414 1.414.707-.707a3.007 3.007 0 0 1 4.243 0 3.005 3.005 0 0 1 0 4.243l-2.122 2.121c-1.133 1.133-3.109 1.133-4.242 0L10.586 12l-1.414 1.414.707.707c.943.944 2.199 1.465 3.535 1.465s2.592-.521 3.535-1.465L19.071 12a5.008 5.008 0 0 0 0-7.071 5.006 5.006 0 0 0-7.071 0z'%3E%3C/path%3E%3C/svg%3E");
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath d='M8.465 11.293c1.133-1.133 3.109-1.133 4.242 0l.707.707 1.414-1.414-.707-.707c-.943-.944-2.199-1.465-3.535-1.465s-2.592.521-3.535 1.465L4.929 12a5.008 5.008 0 0 0 0 7.071 4.983 4.983 0 0 0 3.535 1.462A4.982 4.982 0 0 0 12 19.071l.707-.707-1.414-1.414-.707.707a3.007 3.007 0 0 1-4.243 0 3.005 3.005 0 0 1 0-4.243l2.122-2.121z'%3E%3C/path%3E%3Cpath d='m12 4.929-.707.707 1.414 1.414.707-.707a3.007 3.007 0 0 1 4.243 0 3.005 3.005 0 0 1 0 4.243l-2.122 2.121c-1.133 1.133-3.109 1.133-4.242 0L10.586 12l-1.414 1.414.707.707c.943.944 2.199 1.465 3.535 1.465s2.592-.521 3.535-1.465L19.071 12a5.008 5.008 0 0 0 0-7.071 5.006 5.006 0 0 0-7.071 0z'%3E%3C/path%3E%3C/svg%3E");
}
.pwc-tooltip {
word-wrap: break-word;
position: fixed;
font-family: var(--font-interface);
font-size: var(--pwc-tooltip-font-size);
padding: 10px;
background-color: var(--background-primary);
border: 1px solid var(--background-modifier-border);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
border-radius: 6px;
width: 95vw;
max-width: 300px;
line-height: 1.4;
z-index: var(--layer-popover);
overflow: hidden;
display: flex;
flex-direction: column;
gap: var(--size-4-2);
user-select: text;
}
.pwc-tooltip .csl-entry {
padding: 0;
}
.pwc-tooltips .cm-hmd-barelink {
text-decoration: none;
}
.pwc-tooltips
:not(a, .cm-hmd-internal-link, .cm-link-alias)
> :is(.pandoc-citation, .at).is-resolved {
color: var(--pwc-citation-color);
}
.pwc-tooltips
:not(.cm-formatting-link)
> .cm-pandoc-citation-formatting:not(.at) {
color: var(--pwc-citation-formatting-color);
}
.pwc-tooltips
:not(.cm-hmd-internal-link, .cm-link-alias)
> .cm-pandoc-citation-extra {
color: var(--pwc-citation-extra-color);
}
.pwc-tooltips :not(.cm-link-alias) > :is(.pandoc-citation, .at).is-resolved {
text-decoration: underline;
text-decoration-style: dotted;
text-decoration-thickness: 2px;
text-decoration-color: var(--pwc-citation-underline-color);
}
.pwc-tooltips
:not(.cm-hmd-internal-link, .cm-link-alias)
> :is(.pandoc-citation, .at).is-unresolved {
text-decoration-color: var(--pwc-citation-underline-color-missing);
opacity: 1;
}
.pwc-tooltips
:not(.cm-hmd-internal-link, .cm-link-alias)
> :is(.pandoc-citation, .at).is-unresolved {
color: var(--pwc-citation-color-missing);
}
.pwc-tooltips
:not(a, .cm-hmd-internal-link, .cm-link-alias)
> :is(.pandoc-citation, .at).is-link {
color: var(--link-color);
cursor: var(--cursor-link);
}
.pandoc-citation > * {
pointer-events: none;
}
.pwc-success {
color: var(--interactive-success);
}
.pwc-error {
color: var(--text-error);
}
.pwc-multiselect {
width: 320px;
text-align: left;
font-size: var(--font-ui-small);
}
.pwc-multiselect input {
outline: none !important;
box-shadow: none !important;
font-size: var(--font-ui-small);
height: unset;
}
.pwc-setting-item-wrapper {
flex-direction: column;
align-items: stretch;
}
.pwc-setting-item-wrapper > div {
margin-right: 0 !important;
}
.pwc-setting-item-wrapper > div:last-child {
padding-bottom: 0;
}
.pwc-group-toggle {
display: flex;
justify-content: flex-end;
padding-top: var(--size-4-2);
}
.pwc-group-toggle .setting-item-description {
padding-top: 0;
}
.pwc-suggest-title {
font-size: var(--font-ui-small);
color: var(--text-muted);
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-top: var(--size-4-1);
}
.pwc-suggest-loading-wrapper {
display: flex;
position: relative;
align-items: center;
justify-content: center;
padding: var(--size-4-2) 0;
}
.pwc-suggest-loading,
.pwc-suggest-loading:before,
.pwc-suggest-loading:after {
border-radius: 999px;
width: 1em;
height: 1em;
animation-fill-mode: both;
animation: bblFadInOut 1.6s infinite ease-in-out;
}
.pwc-suggest-loading {
display: block;
color: var(--text-muted);
font-size: 7px;
position: relative;
animation-delay: -0.16s;
top: -1em;
}
.pwc-suggest-loading:before,
.pwc-suggest-loading:after {
content: '';
position: absolute;
}
.pwc-suggest-loading:before {
left: -2em;
animation-delay: -0.32s;
}
.pwc-suggest-loading:after {
left: 2em;
}
@keyframes bblFadInOut {
0%,
80%,
100% {
box-shadow: 0 1em 0 -1.3em;
}
40% {
box-shadow: 0 1em 0 0;
}
}
.pwc-status-icon {
--icon-size: var(--icon-s);
--icon-stroke: var(--icon-s-stroke-width);
}
.pwc-status-icon.is-loading svg {
animation: spin 2s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.suggestion-container.pwc-suggest {
max-width: 500px;
width: 95vw;
}

View file

@ -0,0 +1,277 @@
{
"presets": {
"this_file": "path includes {{query.file.path}}",
"this_folder": "folder includes {{query.file.folder}}",
"this_folder_only": "filter by function task.file.folder === query.file.folder",
"this_root": "root includes {{query.file.root}}",
"hide_date_fields": "# Hide any values for all date fields\nhide due date\nhide scheduled date\nhide start date\nhide created date\nhide done date\nhide cancelled date",
"hide_non_date_fields": "# Hide all the non-date fields, but not tags\nhide id\nhide depends on\nhide recurrence rule\nhide on completion\nhide priority",
"hide_query_elements": "# Hide toolbar, postpone, edit and backlinks\nhide toolbar\nhide postpone button\nhide edit button\nhide backlinks",
"hide_everything": "# Hide everything except description and any tags\npreset hide_date_fields\npreset hide_non_date_fields\npreset hide_query_elements"
},
"globalQuery": "",
"globalFilter": "",
"removeGlobalFilter": false,
"taskFormat": "tasksPluginEmoji",
"setCreatedDate": true,
"setDoneDate": true,
"setCancelledDate": true,
"autoSuggestInEditor": true,
"autoSuggestMinMatch": 0,
"autoSuggestMaxItems": 20,
"provideAccessKeys": true,
"useFilenameAsScheduledDate": true,
"filenameAsScheduledDateFormat": "",
"filenameAsDateFolders": [],
"recurrenceOnNextLine": false,
"removeScheduledDateOnRecurrence": false,
"searchResults": {
"taskCountLocation": "bottom"
},
"statusSettings": {
"coreStatuses": [
{
"symbol": " ",
"name": "Todo",
"nextStatusSymbol": "x",
"availableAsCommand": true,
"type": "TODO"
},
{
"symbol": "x",
"name": "Done",
"nextStatusSymbol": " ",
"availableAsCommand": true,
"type": "DONE"
}
],
"customStatuses": [
{
"symbol": "/",
"name": "In Progress",
"nextStatusSymbol": "x",
"availableAsCommand": true,
"type": "IN_PROGRESS"
},
{
"symbol": "-",
"name": "Cancelled",
"nextStatusSymbol": " ",
"availableAsCommand": true,
"type": "CANCELLED"
},
{
"symbol": " ",
"name": "Unchecked",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "x",
"name": "Checked",
"nextStatusSymbol": " ",
"availableAsCommand": false,
"type": "DONE"
},
{
"symbol": ">",
"name": "Rescheduled",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "<",
"name": "Scheduled",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "!",
"name": "Important",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "?",
"name": "Question",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "*",
"name": "Star",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "n",
"name": "Note",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "l",
"name": "Location",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "i",
"name": "Information",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "I",
"name": "Idea",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "S",
"name": "Amount",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "p",
"name": "Pro",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "c",
"name": "Con",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "b",
"name": "Bookmark",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "\"",
"name": "Quote",
"nextStatusSymbol": "x",
"availableAsCommand": false,
"type": "TODO"
},
{
"symbol": "0",
"name": "Speech bubble 0",
"nextStatusSymbol": "0",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "1",
"name": "Speech bubble 1",
"nextStatusSymbol": "1",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "2",
"name": "Speech bubble 2",
"nextStatusSymbol": "2",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "3",
"name": "Speech bubble 3",
"nextStatusSymbol": "3",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "4",
"name": "Speech bubble 4",
"nextStatusSymbol": "4",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "5",
"name": "Speech bubble 5",
"nextStatusSymbol": "5",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "6",
"name": "Speech bubble 6",
"nextStatusSymbol": "6",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "7",
"name": "Speech bubble 7",
"nextStatusSymbol": "7",
"availableAsCommand": false,
"type": "NON_TASK"
},
{
"symbol": "8",
"name": "Speech bubble 8",
"nextStatusSymbol": "8",
"availableAsCommand": false,
"type": "NON_TASK"
}
]
},
"isShownInEditModal": {
"priority": true,
"recurrence": true,
"due": true,
"scheduled": true,
"start": true,
"before_this": true,
"after_this": true,
"status": true,
"created": true,
"done": true,
"cancelled": true
},
"features": {
"INTERNAL_TESTING_ENABLED_BY_DEFAULT": true
},
"generalSettings": {},
"headingOpened": {
"Core Statuses": true,
"Custom Statuses": true
},
"debugSettings": {
"ignoreSortInstructions": false,
"showTaskHiddenData": false,
"recordTimings": false
},
"loggingOptions": {
"minLevels": {
"": "info",
"tasks": "info",
"tasks.Cache": "info",
"tasks.Events": "info",
"tasks.File": "info",
"tasks.Query": "info",
"tasks.Task": "info"
}
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
{
"id": "obsidian-tasks-plugin",
"name": "Tasks",
"version": "8.0.0",
"minAppVersion": "1.8.7",
"description": "Track tasks across your vault. Supports due dates, recurring tasks, done dates, sub-set of checklist items, and filtering.",
"helpUrl": "https://publish.obsidian.md/tasks/",
"author": "Clare Macrae and Ilyas Landikov (created by Martin Schenck)",
"authorUrl": "https://github.com/obsidian-tasks-group",
"fundingUrl": "https://github.com/sponsors/claremacrae",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

18559
.obsidian/plugins/obsidian-tikzjax/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-tikzjax",
"name": "TikZJax",
"version": "0.5.2",
"minAppVersion": "0.12.0",
"description": "Render LaTeX and TikZ diagrams in your notes",
"author": "artisticat",
"authorUrl": "https://github.com/artisticat1",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
{
"database": "Zotero",
"noteImportFolder": "Thèse/Lectures",
"pdfExportImageDPI": 120,
"pdfExportImageFormat": "jpg",
"pdfExportImageQuality": 90,
"citeFormats": [
{
"name": "Chicago citation",
"format": "formatted-citation",
"cslStyle": "chicago-author-date"
}
],
"exportFormats": [
{
"name": "Note lecture",
"outputPathTemplate": "Thèse/Lectures/@{{citekey}}.md",
"imageOutputPathTemplate": "Meta/Image/{{citekey}}/",
"imageBaseNameTemplate": "image",
"templatePath": "Meta/Modèles/ZI_Template.md",
"cslStyle": "chicago-author-date-16th-edition"
}
],
"citeSuggestTemplate": "[[{{citekey}}]]",
"openNoteAfterImport": true,
"whichNotesToOpenAfterImport": "first-imported-note"
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-zotero-desktop-connector",
"name": "Zotero Integration",
"version": "3.2.1",
"minAppVersion": "1.1.1",
"description": "Insert and import citations, bibliographies, notes, and PDF annotations from Zotero.",
"author": "mgmeyers",
"authorUrl": "https://github.com/mgmeyers/obsidian-zotero-integration",
"isDesktopOnly": true
}

View file

@ -0,0 +1,238 @@
.zt-format {
border: 1px solid var(--background-modifier-border);
padding: 1rem;
background-color: var(--background-primary);
border-radius: 10px;
margin-bottom: 10px;
}
.zt-format__form {
display: flex;
flex-direction: column;
align-items: stretch;
margin-bottom: 1rem;
max-width: 600px;
}
.zt-format__form:last-child {
margin-bottom: 0;
}
.zt-format__label {
font-size: 0.9em;
font-weight: 600;
margin-bottom: 5px;
}
.is-deprecated .zt-format__label {
color: var(--text-error);
}
.zt-format__input-wrapper {
display: flex;
align-items: center;
}
.zt-format__input-wrapper textarea {
resize: vertical;
}
.zt-format__input-wrapper > *:not(.checkbox-container) {
width: 100% !important;
}
.is-deprecated .zt-format__input-wrapper button {
width: auto !important;
flex-grow: 0;
flex-shrink: 0;
margin-left: 5px;
}
.zt-format__delete-btn {
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 7px 9px;
margin-left: 10px;
flex-shrink: 0;
flex-grow: 0;
}
.zt-json-viewer {
font-size: 13px;
}
.zt-json-viewer .react-json-view {
padding: 1em;
border-radius: 10px;
margin-top: 1em;
overflow: auto;
font-family: var(--font-monospace) !important;
}
.zt-json-viewer__btns {
display: flex;
align-items: center;
justify-content: flex-start;
}
.zt-json-viewer__btns label {
display: block;
font-weight: bold;
padding-top: 1em;
}
.zt-json-viewer__btns select {
font-size: 1em;
}
.zt-json-viewer__btns button {
font-size: 1em;
margin-right: 5px;
}
.zt-json-viewer__preview,
.zt-json-viewer__data {
border: 1px solid var(--background-modifier-border);
border-radius: 10px;
padding: 1em;
margin-top: 1em;
}
.zt-json-viewer__preview.error {
background-color: #ff000011;
font-family: var(--font-monospace);
}
.zt-json-viewer__preview pre {
overflow: auto;
white-space: pre-wrap;
margin: 0;
}
.zt-json-viewer__preview pre,
.zt-json-viewer__preview code {
font-family: inherit;
}
.zt-json-viewer__preview:not(.error) pre {
font-family: var(--font-text, --font-default, --default-font);
max-height: 70vh;
min-height: 400px;
}
.zt-multiselect {
width: 300px;
text-align: left;
}
.zt-multiselect input {
outline: none !important;
box-shadow: none !important;
}
.zt-format__input-note {
font-style: italic;
font-size: 0.9em;
padding-top: 10px;
margin-bottom: 10px;
}
.zt-setting-item pre,
.zt-format__input-note pre {
display: inline-block;
margin: 0;
padding: 0 6px;
background-color: var(--background-secondary-alt);
border-radius: 4px;
}
.zt-asset-success {
text-align: left;
display: flex;
}
.zt-asset-success__icon {
color: var(--interactive-success);
font-size: 24px;
margin-right: 5px;
}
.zt-asset-success__icon svg {
width: 1em !important;
height: 1em !important;
}
.zt-asset-success__message {
font-size: 0.9em;
}
.zt-suggest-title {
font-size: var(--font-ui-small);
color: var(--text-muted);
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-top: var(--size-4-1);
}
.zt-suggest-loading-wrapper {
display: flex;
position: relative;
align-items: center;
justify-content: center;
padding: var(--size-4-2) 0;
}
.zt-suggest-loading,
.zt-suggest-loading:before,
.zt-suggest-loading:after {
border-radius: 999px;
width: 1em;
height: 1em;
animation-fill-mode: both;
animation: bblFadInOut 1.6s infinite ease-in-out;
}
.zt-suggest-loading {
display: block;
color: var(--text-muted);
font-size: 7px;
position: relative;
animation-delay: -0.16s;
top: -1em;
}
.zt-suggest-loading:before,
.zt-suggest-loading:after {
content: '';
position: absolute;
}
.zt-suggest-loading:before {
left: -2em;
animation-delay: -0.32s;
}
.zt-suggest-loading:after {
left: 2em;
}
.zt-color-chip {
display: inline-block;
width: 1em;
height: 1em;
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
margin-right: var(--size-4-1);
}
@keyframes bblFadInOut {
0%,
80%,
100% {
box-shadow: 0 1em 0 -1.3em;
}
40% {
box-shadow: 0 1em 0 0;
}
}

View file

@ -0,0 +1,506 @@
--[[
Universal Labeled Example Filter for Pandoc
============================================
Purpose: Transform {::LABEL} syntax into formatted labels for examples and references.
Features:
- Custom labels for list items (e.g., P, Q, Alpha)
- Auto-numbering with (#placeholder) syntax
- Cross-references throughout the document
- Format-specific output (LaTeX/PDF vs Word/DOCX)
Architecture:
1. Label Parser - Extract and parse labels from text
2. Placeholder Manager - Handle auto-numbering
3. Label Registry - Store and retrieve label definitions
4. Output Formatter - Generate format-specific output
5. Main Pipeline - Orchestrate the filter process
--]]
local pandoc = require 'pandoc'
local List = require 'pandoc.List'
-- ============================================================================
-- CONFIGURATION
-- ============================================================================
local Config = {
DEBUG = false,
SYNTAX_PATTERN = "{::([^}]+)}", -- Matches {::anything}
PLACEHOLDER_PATTERN = "%(#([^%)]+)%)", -- Matches (#anything)
}
-- ============================================================================
-- UTILITIES
-- ============================================================================
local Utils = {}
function Utils.debug(msg)
if Config.DEBUG then
io.stderr:write("[DEBUG] " .. msg .. "\n")
end
end
function Utils.format_label(label)
return "(" .. label .. ")"
end
-- ============================================================================
-- PLACEHOLDER MANAGER
-- Handles auto-numbering of (#placeholder) patterns
-- ============================================================================
local PlaceholderManager = {
numbers = {}, -- Map: placeholder_name -> assigned_number
next_number = 1, -- Counter for next assignment
}
function PlaceholderManager:reset()
self.numbers = {}
self.next_number = 1
end
function PlaceholderManager:get_number(placeholder_name)
if not self.numbers[placeholder_name] then
self.numbers[placeholder_name] = self.next_number
self.next_number = self.next_number + 1
Utils.debug("Assigned number " .. self.numbers[placeholder_name] ..
" to placeholder '" .. placeholder_name .. "'")
end
return self.numbers[placeholder_name]
end
function PlaceholderManager:process_label(raw_label)
-- Return label as-is if no placeholders
if not raw_label:match(Config.PLACEHOLDER_PATTERN) then
return raw_label
end
-- Replace all placeholders with their assigned numbers
return raw_label:gsub(Config.PLACEHOLDER_PATTERN, function(placeholder_name)
return tostring(self:get_number(placeholder_name))
end)
end
-- ============================================================================
-- LABEL REGISTRY
-- Stores and manages label definitions and references
-- ============================================================================
local LabelRegistry = {
definitions = {}, -- Map: processed_label -> formatted_label
raw_to_processed = {}, -- Map: raw_label -> processed_label
}
function LabelRegistry:reset()
self.definitions = {}
self.raw_to_processed = {}
end
function LabelRegistry:register(raw_label, processed_label)
-- Always store the raw to processed mapping
self.raw_to_processed[raw_label] = processed_label
if self.definitions[processed_label] then
Utils.debug("Warning: Duplicate label '" .. processed_label .. "'")
else
self.definitions[processed_label] = Utils.format_label(processed_label)
Utils.debug("Registered: raw='" .. raw_label .. "' processed='" .. processed_label ..
"' -> '" .. self.definitions[processed_label] .. "'")
end
end
function LabelRegistry:lookup(raw_label)
-- First check if it's a known raw label
local processed = self.raw_to_processed[raw_label]
if processed and self.definitions[processed] then
return self.definitions[processed]
end
-- Check if it's already a processed label
if self.definitions[raw_label] then
return self.definitions[raw_label]
end
-- For labels with placeholders, only process if we know the base label exists
if raw_label:match(Config.PLACEHOLDER_PATTERN) then
local ref_processed = PlaceholderManager:process_label(raw_label)
if self.definitions[ref_processed] then
return self.definitions[ref_processed]
else
-- Check if this is a pure expression like (#a)+(#b)
-- These are special cases that should be processed
if raw_label:match("^%(#[^%)]+%)") or raw_label:match("%+") then
-- It's an expression with placeholders
return Utils.format_label(ref_processed)
else
-- It's an undefined label with placeholders - don't process
return nil
end
end
end
-- Unknown label
return nil
end
-- ============================================================================
-- LABEL PARSER
-- Extracts and processes labels from inline content
-- ============================================================================
local LabelParser = {}
function LabelParser.extract_label_from_inlines(inlines)
if #inlines == 0 then return nil end
-- Concatenate text to handle split labels
local text = ""
local max_check = math.min(10, #inlines)
for i = 1, max_check do
local elem = inlines[i]
if elem.t == "Str" then
text = text .. elem.text
elseif elem.t == "Space" then
text = text .. " "
else
break
end
-- Check for complete label
local label = text:match("^" .. Config.SYNTAX_PATTERN)
if label then
return label
end
end
return nil
end
function LabelParser.split_by_break(inlines)
local groups = {}
local current = pandoc.List{}
for _, inline in ipairs(inlines) do
if inline.t == "SoftBreak" or inline.t == "LineBreak" then
if #current > 0 then
table.insert(groups, current)
current = pandoc.List{}
end
else
current:insert(inline)
end
end
if #current > 0 then
table.insert(groups, current)
end
return groups
end
-- ============================================================================
-- INLINE PROCESSOR
-- Handles replacement of {::LABEL} patterns in inline content
-- ============================================================================
local InlineProcessor = {}
function InlineProcessor.process_split_label(inlines, start_idx, is_definition, first_in_def)
local text = inlines[start_idx].text
-- Check if this starts a split label
if not (text:match("^{::") and not text:match("}")) then
return nil, start_idx
end
-- Reconstruct the split label
local combined = text
local end_idx = start_idx
for j = start_idx + 1, math.min(#inlines, start_idx + 10) do
local elem = inlines[j]
if elem.t == "Str" then
combined = combined .. elem.text
if elem.text:match("}") then
end_idx = j
break
end
elseif elem.t == "Space" then
combined = combined .. " "
else
break
end
end
-- Extract the label if complete
local raw_label = combined:match(Config.SYNTAX_PATTERN)
if not raw_label then
return nil, start_idx
end
-- Process the label
local replacement
if is_definition and first_in_def then
local processed = LabelRegistry.raw_to_processed[raw_label] or raw_label
replacement = Utils.format_label(processed)
else
replacement = LabelRegistry:lookup(raw_label) or ("{::" .. raw_label .. "}")
end
-- Handle remaining text after the label
local remaining = combined:gsub("^" .. Config.SYNTAX_PATTERN:gsub("%)%}", ")%%}"), "")
if remaining ~= "" then
replacement = replacement .. remaining
end
return pandoc.Str(replacement), end_idx
end
function InlineProcessor.process(inlines, is_definition)
local result = pandoc.List{}
local first_replaced = false
local i = 1
while i <= #inlines do
local elem = inlines[i]
if elem.t == "Str" then
-- Try to handle split label
local replacement, new_idx = InlineProcessor.process_split_label(
inlines, i, is_definition, not first_replaced
)
if replacement then
result:insert(replacement)
if is_definition then first_replaced = true end
i = new_idx + 1
else
-- Process normal text with complete labels
local new_text = elem.text:gsub(Config.SYNTAX_PATTERN, function(raw_label)
if is_definition and not first_replaced then
first_replaced = true
local processed = LabelRegistry.raw_to_processed[raw_label] or raw_label
return Utils.format_label(processed)
else
local replacement = LabelRegistry:lookup(raw_label)
return replacement or ("{::" .. raw_label .. "}")
end
end)
result:insert(pandoc.Str(new_text))
i = i + 1
end
else
result:insert(elem)
i = i + 1
end
end
return result
end
-- ============================================================================
-- OUTPUT FORMATTER
-- Generates format-specific output (LaTeX/Word)
-- ============================================================================
local OutputFormatter = {}
function OutputFormatter.is_word_format()
return FORMAT and (FORMAT:match("docx") or FORMAT:match("odt") or FORMAT:match("rtf"))
end
function OutputFormatter.create_definition_list_item(label, content)
-- Create term
local term = pandoc.List{pandoc.Str(Utils.format_label(label))}
-- Create definition (skip the label part in content)
local def_inlines = pandoc.List{}
local label_pattern = "^%(" .. label:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") .. "%)%s*"
local skip_first = true
for _, inline in ipairs(content) do
if skip_first and inline.t == "Str" then
local text = inline.text:gsub(label_pattern, "")
if text ~= "" then
def_inlines:insert(pandoc.Str(text))
end
skip_first = false
elseif not skip_first then
def_inlines:insert(inline)
end
end
return {term, {{pandoc.Plain(def_inlines)}}}
end
function OutputFormatter.create_word_paragraph(content)
-- Extract label for bold formatting
local label_text = ""
local i = 1
while i <= #content and content[i].t == "Str" do
label_text = label_text .. content[i].text
i = i + 1
if i <= #content and content[i].t == "Space" then
break
end
end
-- Build paragraph with bold label
local result = pandoc.List{pandoc.Strong({pandoc.Str(label_text)})}
if i <= #content then
result:insert(pandoc.Str("\t"))
for j = i + 1, #content do
result:insert(content[j])
end
end
return pandoc.Para(result)
end
-- ============================================================================
-- DOCUMENT SCANNER
-- First pass to identify and register all label definitions
-- ============================================================================
local DocumentScanner = {}
function DocumentScanner.scan(blocks)
local example_blocks = {}
for i, block in ipairs(blocks) do
if block.t == "Para" or block.t == "Plain" then
local groups = LabelParser.split_by_break(block.content)
local has_examples = false
for _, group in ipairs(groups) do
local raw_label = LabelParser.extract_label_from_inlines(group)
if raw_label then
-- Process and register the label
local processed = PlaceholderManager:process_label(raw_label)
LabelRegistry:register(raw_label, processed)
has_examples = true
end
end
if has_examples then
example_blocks[i] = true
end
end
end
return example_blocks
end
-- ============================================================================
-- BLOCK TRANSFORMER
-- Second pass to transform blocks with labels and references
-- ============================================================================
local BlockTransformer = {}
function BlockTransformer.process_example_group(group)
local raw_label = LabelParser.extract_label_from_inlines(group)
if not raw_label then
return nil, nil
end
local processed_label = LabelRegistry.raw_to_processed[raw_label] or raw_label
local processed_inlines = InlineProcessor.process(group, true)
return processed_inlines, processed_label
end
function BlockTransformer.transform(blocks, example_blocks)
local new_blocks = pandoc.List{}
local definition_items = {}
local is_word = OutputFormatter.is_word_format()
for i, block in ipairs(blocks) do
if example_blocks[i] then
-- Process example block
local groups = LabelParser.split_by_break(block.content)
for _, group in ipairs(groups) do
local content, label = BlockTransformer.process_example_group(group)
if content and label then
if is_word then
-- Output any pending definition items first
if #definition_items > 0 then
for _, item in ipairs(definition_items) do
new_blocks:insert(OutputFormatter.create_word_paragraph(item))
end
definition_items = {}
end
-- Create Word paragraph
new_blocks:insert(OutputFormatter.create_word_paragraph(content))
else
-- Accumulate for definition list
table.insert(definition_items,
OutputFormatter.create_definition_list_item(label, content))
end
end
end
else
-- Output pending definition list
if #definition_items > 0 and not is_word then
new_blocks:insert(pandoc.DefinitionList(definition_items))
definition_items = {}
end
-- Process references in regular blocks
if block.t == "Para" then
new_blocks:insert(pandoc.Para(InlineProcessor.process(block.content, false)))
elseif block.t == "Plain" then
new_blocks:insert(pandoc.Plain(InlineProcessor.process(block.content, false)))
else
new_blocks:insert(block)
end
end
end
-- Output any remaining definition items
if #definition_items > 0 and not is_word then
new_blocks:insert(pandoc.DefinitionList(definition_items))
end
return new_blocks
end
-- ============================================================================
-- MAIN FILTER PIPELINE
-- ============================================================================
-- First pass: scan the document and collect all label definitions
function Pandoc(doc)
-- Reset all managers
PlaceholderManager:reset()
LabelRegistry:reset()
-- First pass: scan and register all labels
local example_blocks = DocumentScanner.scan(doc.blocks)
-- Second pass: transform blocks
doc.blocks = BlockTransformer.transform(doc.blocks, example_blocks)
return doc
end
-- Third pass: process all inline content throughout the document
function Inlines(inlines)
-- Process references in all inline content
return InlineProcessor.process(inlines, false)
end
-- Return the filter with two passes
return {
{Pandoc = Pandoc},
{Inlines = Inlines}
}

View file

@ -0,0 +1,938 @@
--[[
Fenced div extended syntax filter for Pandoc.
This monolithic filter handles the fenced-div export features used by the
plugin:
- normalizing readable shorthand such as `::: Theorem #thm key=1`
- adding generated titles for titled/classed Div blocks
- replacing known citations such as `@thm` with numbered reference text
]]
local pandoc = require 'pandoc'
local List = require 'pandoc.List'
local utils = require 'pandoc.utils'
local TEMP_INDEX_ATTRIBUTE = 'data-pem-crossref-index'
local FENCED_DIV_CLASS = 'pem-fenced-div'
local FENCED_DIV_TITLE_CLASS = 'pem-fenced-div-title'
local FENCED_DIV_DOCX_STYLE = 'PEM Fenced Div'
local FENCED_DIV_TITLE_DOCX_STYLE = 'PEM Fenced Div Title'
local PLACEHOLDER_DOT_TOKEN = 'PEMPLACEHOLDERDOT'
local NUMBERING_ESCAPE_CLASSES = {
['no-num'] = true,
['unnumbered'] = true,
}
local split_line_groups = setmetatable({}, { __mode = 'k' })
local split_line_group_counter = 0
local HTML_STYLE_BLOCK = [[
<style>
.pem-fenced-div {
border-left: 2px solid #8a8f98;
margin: 1em 0;
padding-left: 1em;
}
.pem-fenced-div .pem-fenced-div {
margin: 0.75em 0 0.75em 0.75em;
}
.pem-fenced-div > .pem-fenced-div-title,
.pem-fenced-div-title {
display: block;
font-weight: 700;
}
.pem-fenced-div > .pem-fenced-div-title {
margin-bottom: 0.35em;
}
</style>
]]
local LATEX_STYLE_BLOCK = [[
\usepackage[most]{tcolorbox}
\newtcolorbox{PEMFencedDivBox}{
blanker,
breakable,
borderline west={1.5pt}{0pt}{black!45},
left=0.9em,
right=0pt,
top=0.4em,
bottom=0.4em,
before skip=0.8em,
after skip=0.8em
}
]]
local function trim(value)
return (value or ''):gsub('^%s+', ''):gsub('%s+$', '')
end
local function is_html_output()
return FORMAT and FORMAT:match('html') ~= nil
end
local function is_latex_output()
return FORMAT == 'latex' or FORMAT == 'beamer'
end
local function is_custom_style_output()
return FORMAT == 'docx' or FORMAT == 'odt'
end
local function add_class(attr, class_name)
if not attr.classes:includes(class_name) then
attr.classes:insert(class_name)
end
end
local function append_header_include(doc, format, text)
local block = pandoc.RawBlock(format, text)
local header_includes = doc.meta['header-includes']
if not header_includes then
doc.meta['header-includes'] = pandoc.MetaBlocks({ block })
return
end
doc.meta['header-includes'] = pandoc.MetaList({
header_includes,
pandoc.MetaBlocks({ block }),
})
end
local function strip_quotes(value)
if #value < 2 then
return value
end
local quote = value:sub(1, 1)
if (quote ~= '"' and quote ~= "'") or value:sub(-1) ~= quote then
return value
end
local result = ''
local escaped = false
for index = 2, #value - 1 do
local char = value:sub(index, index)
if escaped then
if char == '&' then
result = result .. '\\' .. char
else
result = result .. char
end
escaped = false
elseif char == '\\' then
escaped = true
else
result = result .. char
end
end
return escaped and result .. '\\' or result
end
local function split_attribute_tokens(text)
local tokens = {}
local current = ''
local quote = nil
local escaped = false
for index = 1, #text do
local char = text:sub(index, index)
if escaped then
current = current .. char
escaped = false
elseif char == '\\' and quote then
current = current .. char
escaped = true
elseif (char == '"' or char == "'") and not quote then
quote = char
current = current .. char
elseif char == quote then
quote = nil
current = current .. char
elseif char:match('%s') and not quote then
if current ~= '' then
table.insert(tokens, current)
current = ''
end
else
current = current .. char
end
end
if quote or escaped then
return nil
end
if current ~= '' then
table.insert(tokens, current)
end
return tokens
end
local function is_attribute_key(key)
return key:match('^[A-Za-z:][A-Za-z0-9_:%.%-]*$') ~= nil
end
local function is_readable_class(token)
return token:match('^[^%s#={},]+$') ~= nil and token:match('^:+$') == nil
end
local function is_numbering_escape_class(class_name)
return NUMBERING_ESCAPE_CLASSES[(class_name or ''):lower()] == true
end
local function find_first_placeholder_group(value)
local escaped = false
for index = 1, #value do
local char = value:sub(index, index)
if escaped then
escaped = false
elseif char == '\\' then
escaped = true
elseif char == '&' then
local group_end = index
local depth = 1
while value:sub(group_end + 1, group_end + 1) == '.' and
value:sub(group_end + 2, group_end + 2) == '&' do
depth = depth + 1
group_end = group_end + 2
end
return {
start = index,
finish = group_end,
depth = depth,
}
end
end
return nil
end
local function is_placeholder_only_title(value)
local placeholder_group = find_first_placeholder_group(value or '')
return placeholder_group ~= nil and
placeholder_group.start == 1 and
placeholder_group.finish == #value
end
local function preserve_placeholder_dots(value)
local result = ''
for index = 1, #value do
local char = value:sub(index, index)
if char == '.' and value:sub(index - 1, index - 1) == '&' and value:sub(index + 1, index + 1) == '&' then
result = result .. PLACEHOLDER_DOT_TOKEN
else
result = result .. char
end
end
return result
end
local function humanize_class_name(class_name)
local text = preserve_placeholder_dots(class_name or '')
:gsub('[_:%-]+', ' ')
:gsub('%.', ' ')
:gsub('%s+', ' ')
:gsub(PLACEHOLDER_DOT_TOKEN, '.')
text = trim(text)
if text == '' then
return ''
end
return (text:gsub('(%f[%a]%a)', string.upper))
end
local function synthesize_title_from_classes(classes)
local title_parts = {}
for _, class_name in ipairs(classes or {}) do
if not is_numbering_escape_class(class_name) then
table.insert(title_parts, humanize_class_name(class_name))
end
end
if #title_parts == 0 then
return ''
end
local placeholder_index = nil
for index, part in ipairs(title_parts) do
if find_first_placeholder_group(part) then
placeholder_index = index
break
end
end
if not placeholder_index then
return title_parts[1] or ''
end
if not is_placeholder_only_title(title_parts[placeholder_index]) then
return title_parts[placeholder_index] or ''
end
local title_index = nil
for index, part in ipairs(title_parts) do
if not is_placeholder_only_title(part) then
title_index = index
break
end
end
if not title_index then
return title_parts[placeholder_index] or ''
end
if placeholder_index < title_index then
return title_parts[placeholder_index] .. ' ' .. title_parts[title_index]
end
return title_parts[title_index] .. ' ' .. title_parts[placeholder_index]
end
local function has_title_key(key_values)
for _, pair in ipairs(key_values or {}) do
if pair[1] == 'title' then
return true
end
end
return false
end
local function with_synthesized_title(opening)
if has_title_key(opening.key_values) then
return opening
end
local title = synthesize_title_from_classes(opening.classes)
if title ~= '' then
table.insert(opening.key_values, {'title', title})
end
return opening
end
local function parse_key_value(token)
local separator = token:find('=', 1, true)
if not separator then
return nil
end
local key = token:sub(1, separator - 1)
if not is_attribute_key(key) then
return nil
end
return key, strip_quotes(token:sub(separator + 1))
end
local function find_closing_brace(value, start_index)
local quote = nil
local escaped = false
for index = start_index, #value do
local char = value:sub(index, index)
if escaped then
escaped = false
elseif char == '\\' and quote then
escaped = true
elseif (char == '"' or char == "'") and not quote then
quote = char
elseif char == quote then
quote = nil
elseif char == '}' and not quote then
return index
end
end
return nil
end
local function parse_native_braced_attributes(braced_text)
local ok, doc = pcall(pandoc.read, '::: ' .. braced_text .. '\n:::', 'markdown')
if not ok or not doc.blocks or #doc.blocks ~= 1 or doc.blocks[1].t ~= 'Div' then
return nil
end
local div = doc.blocks[1]
local key_values = {}
for key, value in pairs(div.attributes or {}) do
table.insert(key_values, {key, value})
end
return {
id = div.identifier or '',
classes = div.classes or {},
key_values = key_values,
}
end
local function with_title(opening, title)
table.insert(opening.key_values, {'title', title})
return opening
end
local function parse_braced_title_after_attributes(attributes)
if attributes:sub(1, 1) ~= '{' then
return nil
end
local closing_brace = find_closing_brace(attributes, 1)
if not closing_brace then
return nil
end
local title = trim(attributes:sub(closing_brace + 1))
if title == '' then
return nil
end
local opening = parse_native_braced_attributes(attributes:sub(1, closing_brace))
return opening and with_title(opening, title) or nil
end
local function parse_braced_title_before_attributes(attributes)
if attributes:sub(-1) ~= '}' then
return nil
end
for index = 1, #attributes do
if attributes:sub(index, index) == '{' then
local closing_brace = find_closing_brace(attributes, index)
if closing_brace == #attributes then
local title = trim(attributes:sub(1, index - 1))
if title == '' then
return nil
end
local opening = parse_native_braced_attributes(attributes:sub(index, closing_brace))
return opening and with_title(opening, title) or nil
end
end
end
return nil
end
local function parse_readable_opening(text)
local attributes = text:match('^:::+%s+(.+)$')
if not attributes then
return nil
end
attributes = attributes:gsub('%s+:+%s*$', '')
if attributes == '' then
return nil
end
local braced_opening = parse_braced_title_after_attributes(attributes) or
parse_braced_title_before_attributes(attributes)
if braced_opening then
return braced_opening
end
local tokens = split_attribute_tokens(attributes)
if not tokens or #tokens == 0 then
return nil
end
local id = ''
local classes = {}
local key_values = {}
for _, token in ipairs(tokens) do
local parsed_id = token:match('^#([^%s@,=]+)$')
if parsed_id then
id = parsed_id
elseif token:find('=', 1, true) then
local key, value = parse_key_value(token)
if not key then
return nil
end
table.insert(key_values, {key, value})
elseif is_readable_class(token) then
table.insert(classes, token)
else
return nil
end
end
return with_synthesized_title({
id = id,
classes = classes,
key_values = key_values,
})
end
local function is_readable_closing(text)
return text:match('^:::+%s*$') ~= nil
end
local function is_atx_heading(text)
local hashes = text:match('^(#+)')
if not hashes or #hashes > 6 then
return false
end
local next_char = text:sub(#hashes + 1, #hashes + 1)
return next_char == '' or next_char:match('%s') ~= nil
end
local function is_thematic_break(text)
return text:match('^(%*%s*)%*%s*%*[%*%s]*$') ~= nil or
text:match('^(%-%s*)%-%s*%-[%-%s]*$') ~= nil or
text:match('^(_%s*)_%s*_[_%s]*$') ~= nil
end
local function is_single_line_html_block(text)
local tag = text:match('^<([A-Za-z][A-Za-z0-9%-]*)(%s[^>]*)?>.*</%1>$')
if not tag then
return false
end
local block_tags = {
address = true, article = true, aside = true, base = true,
basefont = true, blockquote = true, body = true, caption = true,
center = true, col = true, colgroup = true, dd = true,
details = true, dialog = true, dir = true, div = true,
dl = true, dt = true, fieldset = true, figcaption = true,
figure = true, footer = true, form = true, frame = true,
frameset = true, h1 = true, h2 = true, h3 = true,
h4 = true, h5 = true, h6 = true, head = true,
header = true, hr = true, html = true, iframe = true,
legend = true, li = true, link = true, main = true,
menu = true, menuitem = true, nav = true, noframes = true,
ol = true, optgroup = true, option = true, p = true,
param = true, search = true, section = true, summary = true,
table = true, tbody = true, td = true, tfoot = true,
th = true, thead = true, title = true, tr = true,
track = true, ul = true,
}
return block_tags[tag:lower()] == true
end
local function allows_readable_opening_after_line(text)
local trimmed = trim(text or '')
return trimmed == '' or
is_atx_heading(trimmed) or
is_thematic_break(trimmed) or
is_single_line_html_block(trimmed)
end
local function split_inline_lines(inlines)
local lines = List{}
local current = List{}
for _, inline in ipairs(inlines) do
if inline.t == 'SoftBreak' or inline.t == 'LineBreak' then
lines:insert(current)
current = List{}
else
current:insert(inline)
end
end
lines:insert(current)
return lines
end
local function block_text(block)
if block.t ~= 'Para' and block.t ~= 'Plain' then
return nil
end
return utils.stringify(block.content)
end
local function block_contains_processable_readable_fence_lines(block)
if block.t ~= 'Para' and block.t ~= 'Plain' then
return false
end
local can_open = true
for _, line in ipairs(split_inline_lines(block.content)) do
local text = utils.stringify(line)
if can_open and parse_readable_opening(text) then
return true
end
can_open = allows_readable_opening_after_line(text)
end
return false
end
local function expand_fence_paragraphs(blocks)
local expanded = List{}
for _, block in ipairs(blocks) do
if block_contains_processable_readable_fence_lines(block) then
split_line_group_counter = split_line_group_counter + 1
for _, line in ipairs(split_inline_lines(block.content)) do
local paragraph = pandoc.Para(line)
split_line_groups[paragraph] = split_line_group_counter
expanded:insert(paragraph)
end
else
expanded:insert(block)
end
end
return expanded
end
local normalize_readable_blocks
local function normalize_child_blocks(block)
if block.t == 'BlockQuote' then
return pandoc.BlockQuote(normalize_readable_blocks(block.content))
end
if block.t == 'Div' then
return pandoc.Div(normalize_readable_blocks(block.content), block.attr)
end
if block.t == 'BulletList' or block.t == 'OrderedList' then
local items = List{}
for _, item in ipairs(block.content) do
items:insert(normalize_readable_blocks(item))
end
if block.t == 'BulletList' then
return pandoc.BulletList(items)
end
return pandoc.OrderedList(items, block.listAttributes)
end
return block
end
local function parse_readable_sequence(blocks, start_index, stop_on_close)
local result = List{}
local index = start_index
local can_open = true
local active_split_group = nil
while index <= #blocks do
local block = blocks[index]
local text = block_text(block)
local split_group = split_line_groups[block]
if split_group ~= active_split_group then
active_split_group = split_group
can_open = true
elseif not split_group then
can_open = true
end
if text and is_readable_closing(text) then
if stop_on_close then
return result, index + 1, true
end
result:insert(block)
index = index + 1
can_open = true
else
local opening = can_open and text and parse_readable_opening(text) or nil
if opening then
local inner, next_index, closed = parse_readable_sequence(blocks, index + 1, true)
if closed then
result:insert(pandoc.Div(
inner,
pandoc.Attr(opening.id, opening.classes, opening.key_values)
))
index = next_index
can_open = true
else
io.stderr:write('[FencedDivExtendedSyntax] unmatched readable fenced div opener; leaving content unchanged\n')
result:insert(block)
for _, inner_block in ipairs(inner) do
result:insert(inner_block)
end
return result, next_index, false
end
else
result:insert(normalize_child_blocks(block))
index = index + 1
if split_group and text then
can_open = allows_readable_opening_after_line(text)
else
can_open = true
end
end
end
end
return result, index, false
end
function normalize_readable_blocks(blocks)
local expanded = expand_fence_paragraphs(blocks)
local normalized = parse_readable_sequence(expanded, 1, false)
return normalized
end
local function title_for_div(div)
local title = trim(div.attributes and div.attributes.title or '')
if title ~= '' then
return title
end
for _, class_name in ipairs(div.classes or {}) do
local raw_title = class_name:match('^title=(.+)$')
if raw_title then
return trim(strip_quotes(raw_title))
end
end
return ''
end
local function has_numbering_escape_class(div)
for _, class_name in ipairs(div.classes or {}) do
if is_numbering_escape_class(class_name) then
return true
end
end
return false
end
local function title_stem(title)
local placeholder_group = find_first_placeholder_group(title or '')
local stem = title or ''
if placeholder_group then
stem = stem:sub(1, placeholder_group.start - 1) .. stem:sub(placeholder_group.finish + 1)
end
stem = stem:gsub('\\&', '&')
return trim(stem:gsub('[^%w%s]+', ' '):gsub('%s+', ' '))
end
local function class_label_for_div(div)
for _, class_name in ipairs(div.classes or {}) do
if not is_numbering_escape_class(class_name) and not is_placeholder_only_title(humanize_class_name(class_name)) then
return humanize_class_name(class_name)
end
end
return ''
end
local function title_template_for_div(div)
return title_for_div(div)
end
local function should_number_div(div)
local title = title_template_for_div(div)
return find_first_placeholder_group(title) ~= nil and not has_numbering_escape_class(div)
end
local function render_numbered_title(title, number_parts)
local placeholder_group = find_first_placeholder_group(title or '')
if not placeholder_group then
return (title or ''):gsub('\\&', '&')
end
local index = 0
local group = title:sub(placeholder_group.start, placeholder_group.finish):gsub('&', function()
index = index + 1
return tostring(number_parts[index] or 0)
end)
return (
title:sub(1, placeholder_group.start - 1) ..
group ..
title:sub(placeholder_group.finish + 1)
):gsub('\\&', '&')
end
local function type_label_for_div(div, numbering_enabled)
local title = title_template_for_div(div)
if title ~= '' then
return numbering_enabled and title_stem(title) or title:gsub('\\&', '&')
end
local class_label = class_label_for_div(div)
return class_label ~= '' and class_label or 'Div'
end
local function should_render_block_title(div)
if title_for_div(div) ~= '' then
return true
end
for _, class_name in ipairs(div.classes or {}) do
if not is_numbering_escape_class(class_name) and not is_placeholder_only_title(humanize_class_name(class_name)) then
return true
end
end
return false
end
local function type_key_for_label(label)
local key = label:lower():gsub('[^a-z0-9]+', '-'):gsub('^-+', ''):gsub('-+$', '')
return key == '' and 'div' or key
end
local function is_generated_title_block(block)
return block and
block.t == 'Div' and
block.classes and
block.classes:includes(FENCED_DIV_TITLE_CLASS)
end
local function title_block(reference)
local attributes = {}
local title_inline = pandoc.Str(reference.block_title_text)
if is_custom_style_output() then
attributes = {
{ 'custom-style', FENCED_DIV_TITLE_DOCX_STYLE },
}
title_inline = pandoc.Span(
{ title_inline },
pandoc.Attr('', {}, {
{ 'custom-style', FENCED_DIV_TITLE_DOCX_STYLE },
})
)
end
return pandoc.Div(
{ pandoc.Plain({ pandoc.Strong({ title_inline }) }) },
pandoc.Attr('', { FENCED_DIV_TITLE_CLASS }, attributes)
)
end
local function register_div(div, state)
local title_template = title_template_for_div(div)
local numbering_enabled = should_number_div(div)
local type_label = type_label_for_div(div, numbering_enabled)
local type_key = type_key_for_label(type_label)
local number_parts = {}
local number = 0
local reference_text = type_label
if numbering_enabled then
local depth = find_first_placeholder_group(title_template).depth
local current_parts = state.counters[type_key] or {}
for index = 1, depth - 1 do
number_parts[index] = current_parts[index] or 1
end
number_parts[depth] = (current_parts[depth] or 0) + 1
state.counters[type_key] = number_parts
number = number_parts[#number_parts] or 0
reference_text = render_numbered_title(title_template, number_parts)
end
local reference = {
type_label = type_label,
type_key = type_key,
number = number,
number_parts = number_parts,
numbering_enabled = numbering_enabled,
reference_text = reference_text,
block_title_text = should_render_block_title(div) and
reference_text or ''
}
table.insert(state.div_metadata, reference)
local id = div.identifier
if id and id ~= '' and not state.references[id] then
state.references[id] = reference
end
div.attributes[TEMP_INDEX_ATTRIBUTE] = tostring(#state.div_metadata)
end
local function scan_blocks(blocks, state)
for _, block in ipairs(blocks) do
if block.t == 'Div' then
if not is_generated_title_block(block) then
register_div(block, state)
end
scan_blocks(block.content, state)
elseif block.t == 'BlockQuote' then
scan_blocks(block.content, state)
elseif block.t == 'BulletList' or block.t == 'OrderedList' then
for _, item in ipairs(block.content) do
scan_blocks(item, state)
end
elseif block.t == 'DefinitionList' then
for _, item in ipairs(block.content) do
for _, definition in ipairs(item[2]) do
scan_blocks(definition, state)
end
end
end
end
end
local function has_affixes(citation)
return (citation.prefix and #citation.prefix > 0) or
(citation.suffix and #citation.suffix > 0)
end
local function cross_reference_filter(state)
return {
Cite = function(cite_node)
if #cite_node.citations ~= 1 then
return nil
end
local citation = cite_node.citations[1]
if has_affixes(citation) then
return nil
end
local reference = state.references[citation.id]
return reference and pandoc.Str(reference.reference_text) or nil
end,
Div = function(div_node)
local index = tonumber(div_node.attributes[TEMP_INDEX_ATTRIBUTE] or '')
div_node.attributes[TEMP_INDEX_ATTRIBUTE] = nil
local reference = index and state.div_metadata[index] or nil
if not reference then
return nil
end
if reference.block_title_text ~= '' and not is_generated_title_block(div_node.content[1]) then
div_node.content:insert(1, title_block(reference))
end
add_class(div_node.attr, FENCED_DIV_CLASS)
if is_custom_style_output() then
div_node.attributes['custom-style'] = FENCED_DIV_DOCX_STYLE
end
if is_latex_output() then
local wrapped = List{ pandoc.RawBlock('latex', '\\begin{PEMFencedDivBox}') }
for _, block in ipairs(div_node.content) do
wrapped:insert(block)
end
wrapped:insert(pandoc.RawBlock('latex', '\\end{PEMFencedDivBox}'))
return wrapped
end
return div_node
end,
}
end
local function process_doc(doc)
doc.blocks = normalize_readable_blocks(doc.blocks)
local state = {
references = {},
div_metadata = {},
counters = {},
}
scan_blocks(doc.blocks, state)
doc = doc:walk(cross_reference_filter(state))
if #state.div_metadata > 0 then
if is_html_output() then
append_header_include(doc, 'html', HTML_STYLE_BLOCK)
elseif is_latex_output() then
append_header_include(doc, 'latex', LATEX_STYLE_BLOCK)
end
end
return doc
end
return {
{
Pandoc = process_doc,
},
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "pandoc-extended-markdown",
"name": "Pandoc Extended Markdown",
"version": "1.8.0",
"minAppVersion": "1.4.0",
"description": "Render Pandoc extended markdown syntax: fancy lists, definition lists, example lists with cross-references, superscripts, and subscripts.",
"author": "ErrorTzy",
"authorUrl": "https://github.com/ErrorTzy",
"isDesktopOnly": false
}

File diff suppressed because it is too large Load diff

14890
.obsidian/plugins/pseudocode-in-obs/main.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
{
"id": "pseudocode-in-obs",
"name": "Pseudocode",
"version": "1.6.5",
"minAppVersion": "0.15.0",
"description": "This is an obsidian plugin that helps to render a LaTeX-style pseudocode inside a code block.",
"author": "Yaotian Liu",
"authorUrl": "https://github.com/ytliu74",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
{
"id": "qmd-as-md-obsidian",
"version": "0.4.3",
"description": "View, edit, preview and render Quarto (.qmd) files. Quarto combines Markdown with executable code cells.",
"name": "qmd as md",
"author": "Daniel Borek",
"authorUrl": "https://github.com/danieltomasz",
"isDesktopOnly": true,
"minAppVersion": "1.8.0"
}

View file

@ -0,0 +1,174 @@
/* Quarto outline sidebar view (QmdOutlineView) */
.qmd-outline {
padding: var(--size-4-2) var(--size-4-1);
}
.qmd-outline-empty {
padding: var(--size-4-2) var(--size-4-3);
color: var(--text-muted);
font-size: var(--font-ui-small);
}
.qmd-outline-list {
display: flex;
flex-direction: column;
}
.qmd-outline-item {
display: flex;
align-items: center;
gap: var(--size-2-1);
padding: var(--size-2-1) var(--size-4-3);
border-radius: var(--radius-s);
color: var(--text-muted);
font-size: var(--font-ui-small);
cursor: pointer;
}
/* Chevron slot — always present so leaf and parent headings align. */
.qmd-outline-toggle {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
width: var(--size-4-4);
height: var(--size-4-4);
color: var(--text-faint);
transition: transform 100ms ease-in-out;
}
.qmd-outline-toggle .svg-icon {
width: var(--icon-xs, 14px);
height: var(--icon-xs, 14px);
}
/* Collapsed: chevron points right, sub-tree hidden. */
.qmd-outline-item.is-collapsed .qmd-outline-toggle {
transform: rotate(-90deg);
}
.qmd-outline-children.is-collapsed {
display: none;
}
.qmd-outline-item-text {
flex: 1 1 auto;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.qmd-outline-item:hover {
background-color: var(--background-modifier-hover);
color: var(--text-normal);
}
.qmd-outline-item:focus-visible {
outline: 2px solid var(--interactive-accent);
outline-offset: -2px;
color: var(--text-normal);
}
/* Indentation by heading level driven by the data-level attribute so the
view itself sets no inline styles. Each level adds one --size-4-4 step. */
.qmd-outline-item[data-level='1'] { padding-left: var(--size-4-3); }
.qmd-outline-item[data-level='2'] { padding-left: calc(var(--size-4-3) + var(--size-4-4)); }
.qmd-outline-item[data-level='3'] { padding-left: calc(var(--size-4-3) + var(--size-4-4) * 2); }
.qmd-outline-item[data-level='4'] { padding-left: calc(var(--size-4-3) + var(--size-4-4) * 3); }
.qmd-outline-item[data-level='5'] { padding-left: calc(var(--size-4-3) + var(--size-4-4) * 4); }
.qmd-outline-item[data-level='6'] { padding-left: calc(var(--size-4-3) + var(--size-4-4) * 5); }
/* Code editor views (QmdCodeFileView — YAML and Lua files) */
.qmd-code-view {
height: 100%;
padding: 0;
overflow: hidden;
background: var(--background-primary);
}
.qmd-code-view .cm-editor {
height: 100%;
background: var(--background-primary);
color: var(--text-normal);
font-family: var(--font-monospace);
font-size: var(--font-ui-small);
line-height: var(--line-height-tight);
outline: none;
}
.qmd-code-view .cm-scroller {
font-family: var(--font-monospace);
font-size: var(--font-ui-small);
line-height: var(--line-height-tight);
}
.qmd-code-view .cm-content {
min-height: 100%;
padding: var(--size-4-4);
caret-color: var(--text-normal);
tab-size: 2;
}
.qmd-code-view .cm-focused {
box-shadow: inset 0 0 0 2px var(--interactive-accent);
}
.qmd-code-view.qmd-code-view .cm-editor .cm-selectionBackground {
background: var(--text-selection);
}
.qmd-yaml-key {
color: var(--text-accent);
font-weight: 600;
}
.qmd-yaml-colon,
.qmd-yaml-list-marker,
.qmd-yaml-doc-marker {
color: var(--text-faint);
font-weight: 600;
}
.qmd-yaml-string {
color: var(--text-normal);
}
.qmd-yaml-number,
.qmd-yaml-boolean,
.qmd-yaml-anchor,
.qmd-yaml-block,
.qmd-yaml-quarto-format {
color: var(--interactive-accent);
}
.qmd-yaml-comment {
color: var(--text-muted);
font-style: italic;
}
.qmd-yaml-scalar {
color: var(--text-normal);
}
/* Lua editor view tokens */
.qmd-lua-keyword {
color: var(--text-accent);
font-weight: 600;
}
.qmd-lua-string {
color: var(--interactive-accent);
}
.qmd-lua-number {
color: var(--interactive-accent);
}
.qmd-lua-comment {
color: var(--text-muted);
font-style: italic;
}

View file

@ -0,0 +1,44 @@
{
"command_timeout": 5,
"templates_folder": "Meta/Modèles",
"templates_pairs": [
[
"",
""
]
],
"trigger_on_file_creation": false,
"auto_jump_to_cursor": false,
"enable_system_commands": false,
"shell_path": "",
"user_scripts_folder": "",
"enable_folder_templates": true,
"folder_templates": [
{
"folder": "",
"template": ""
}
],
"enable_file_templates": false,
"file_templates": [
{
"regex": ".*",
"template": ""
}
],
"syntax_highlighting": true,
"syntax_highlighting_mobile": false,
"enabled_templates_hotkeys": [
"Meta/Modèles/Séminaire_Template.md",
""
],
"startup_templates": [
""
],
"intellisense_render": 1,
"ignore_folders_on_creation": [
{
"folder": ""
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,17 @@
{
"id": "templater-obsidian",
"name": "Templater",
"version": "2.20.5",
"description": "Advanced templating and automation using handlebars-like syntax.",
"minAppVersion": "1.12.2",
"author": "SilentVoid",
"authorUrl": "https://github.com/SilentVoid13",
"fundingUrl": {
"GitHub Sponser (Zachatoo, maintainer)": "https://github.com/sponsors/Zachatoo",
"Ko-fi (Zachatoo, maintainer)": "https://ko-fi.com/zachatoo",
"GitHub Sponser (SilentVoid13, creator)": "https://github.com/sponsors/SilentVoid13",
"Paypal (SilentVoid13, creator)": "https://www.paypal.com/donate?hosted_button_id=U2SRGAFYXT32Q"
},
"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: #0088ff;
color: white;
}

3
.obsidian/templates.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"folder": "Meta/Modèles"
}

29
.obsidian/types.json vendored Normal file
View file

@ -0,0 +1,29 @@
{
"types": {
"aliases": "aliases",
"cssclasses": "multitext",
"tags": "tags",
"TQ_explain": "checkbox",
"TQ_extra_instructions": "text",
"TQ_short_mode": "checkbox",
"TQ_show_backlink": "checkbox",
"TQ_show_cancelled_date": "checkbox",
"TQ_show_created_date": "checkbox",
"TQ_show_depends_on": "checkbox",
"TQ_show_done_date": "checkbox",
"TQ_show_due_date": "checkbox",
"TQ_show_edit_button": "checkbox",
"TQ_show_id": "checkbox",
"TQ_show_on_completion": "checkbox",
"TQ_show_postpone_button": "checkbox",
"TQ_show_priority": "checkbox",
"TQ_show_recurrence_rule": "checkbox",
"TQ_show_scheduled_date": "checkbox",
"TQ_show_start_date": "checkbox",
"TQ_show_tags": "checkbox",
"TQ_show_task_count": "checkbox",
"TQ_show_toolbar": "checkbox",
"TQ_show_tree": "checkbox",
"TQ_show_urgency": "checkbox"
}
}

298
.obsidian/workspace.json vendored Normal file
View file

@ -0,0 +1,298 @@
{
"main": {
"id": "bc1cf8a7cb1e201e",
"type": "split",
"children": [
{
"id": "1cf21b6cf48676e1",
"type": "tabs",
"children": [
{
"id": "5a22d122169dedf7",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Thèse/Articles/Review papier colBiSBM.md",
"mode": "source",
"source": false,
"backlinks": false
},
"icon": "lucide-file",
"title": "Review papier colBiSBM"
}
},
{
"id": "0d871c9c302106bd",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Résumé des tâches.md",
"mode": "source",
"source": false,
"backlinks": false
},
"icon": "lucide-file",
"title": "Résumé des tâches"
}
},
{
"id": "2ae79305475d0e4e",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Thèse/Lectures/@quericBridgingMaximumLikelihood2026.md",
"mode": "source",
"source": false,
"backlinks": false
},
"icon": "lucide-file",
"title": "@quericBridgingMaximumLikelihood2026"
}
}
],
"currentTab": 2
}
],
"direction": "vertical"
},
"left": {
"id": "9af3453185975b08",
"type": "split",
"children": [
{
"id": "1d201ebae5473f34",
"type": "tabs",
"children": [
{
"id": "5f4f3b632d81a4d2",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Explorateur de fichiers"
}
},
{
"id": "278ae1cfdabddbad",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Rechercher"
}
},
{
"id": "df90a46984e5f7b7",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Signets"
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "c1ebccab0428fa5b",
"type": "split",
"children": [
{
"id": "4ed59e4175a6ebe0",
"type": "tabs",
"children": [
{
"id": "953a54d708c9215f",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "Thèse/Lectures/Tutoriel ABC.qmd",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Rétrolien pour Tutoriel ABC"
}
},
{
"id": "d95016319967ecbe",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "Thèse/Lectures/Tutoriel ABC.qmd",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Liens sortants de Tutoriel ABC"
}
},
{
"id": "c733b1f53194bf3a",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Mots-clés"
}
},
{
"id": "c6b4c511b017eb90",
"type": "leaf",
"state": {
"type": "all-properties",
"state": {
"sortOrder": "frequency",
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-archive",
"title": "Toutes les propriétés"
}
},
{
"id": "df6b43114384f30e",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "Thèse/Lectures/@turnerTutorialApproximateBayesian2012.qmd",
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Plan de @turnerTutorialApproximateBayesian2012"
}
},
{
"id": "1b833d559a5f999e",
"type": "leaf",
"state": {
"type": "list-panel-view",
"state": {},
"icon": "list-panel-view",
"title": "List panel"
}
},
{
"id": "d2d889e4aac458c5",
"type": "leaf",
"state": {
"type": "footnotes",
"state": {
"file": "Thèse/Lectures/@turnerTutorialApproximateBayesian2012.qmd"
},
"icon": "lucide-file-signature",
"title": "Notes de bas de page"
}
},
{
"id": "1d317f3340ffee42",
"type": "leaf",
"state": {
"type": "ReferenceListView",
"state": {},
"icon": "quote-glyph",
"title": "References"
}
}
],
"currentTab": 7
}
],
"direction": "horizontal",
"width": 218.5
},
"left-ribbon": {
"hiddenItems": {
"switcher:Ouvrir le sélecteur rapide": false,
"graph:Ouvrir la vue graphique": false,
"canvas:Créer une nouvelle toile": false,
"daily-notes:Ouvrir la note quotidienne": false,
"templates:Insérer le modèle": false,
"command-palette:Ouvrir la palette de commandes": false,
"bases:Créer une nouvelle base": false,
"obsidian-livesync:Replicate": false,
"obsidian-livesync:Show Log": false,
"qmd-as-md-obsidian:Render Quarto to PDF": false,
"pandoc-extended-markdown:Open list panel": false,
"obsidian-livesync:Afficher la synchronisation de personnalisation": false,
"qmd-as-md-obsidian:Toggle Quarto preview": false,
"obsidian-livesync:P2P Status": false,
"obsidian-git:Open Git source control": false,
"templater-obsidian:Templater": false
}
},
"active": "2ae79305475d0e4e",
"lastOpenFiles": [
"Résumé des tâches.md",
"Thèse/Lectures/@quericBridgingMaximumLikelihood2026.md",
"Thèse/TODO/2026-05-18.md",
"Thèse/Résumés séminaires.md",
"Thèse/Séminaires/2026-06-09 VICTOR François.md",
"Thèse/Séminaires/2026-06-09 FRANCHETERRE Blanche.md",
"Thèse/Articles/Review papier colBiSBM.md",
"Perso/Tâches/2026-05-17.md",
"Thèse/Axes/Phylogénie/SBM avec covariance latente.md",
"Thèse/Axes/projets-phylo.qmd",
"Thèse/Tutoriel ABC.md",
"Bienvenue.md",
"Thèse/Lectures/@turnerTutorialApproximateBayesian2012.md",
"Thèse/Lectures/@hronImputationMissingValues2010.md",
"Thèse/Axes/Phylogénie/SBM avec covariance multinomiale probit.md",
"Thèse/Axes/Phylogénie/Phylogénie Papiers à regarder.md",
"Perso/Tâches/Casque antibruit pour l'anniversaire de Kris.md",
"Thèse/StateOfTheR/HappyR/2026-05-29 MLOps en Python.md",
"@boraCompressedSensingUsing2017.md",
"Thèse/StateOfTheR/HappyR/Sans titre",
"Thèse/StateOfTheR/HappyR",
"Thèse/StateOfTheR",
"Thèse/Groupes de travail/Modèles génératifs/VAE pour la régularisation de problème inverse.md",
"Thèse/Séminaires/2026-05-28 SILVA BERNARDES Juliana.md",
"Thèse/Groupes de travail/Modèles génératifs",
"Thèse/Groupes de travail",
"Meta/Modèles/Séminaire_Template.md",
"Thèse/Séminaires/2026-05-28 NOM.md",
"Thèse/Séminaires/2026-05-28.md",
"Thèse/Séminaires/null.md",
"2026-05-28.md",
"Thèse/Séminaires/Untitled.md",
"public/index-listing.json",
"index-listing.json",
"site_libs/quarto-listing/quarto-listing.js",
"site_libs/quarto-listing/list.min.js"
]
}

2273
.pandoc/apa.csl Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

864
.pandoc/locales-en-US.xml Normal file
View file

@ -0,0 +1,864 @@
<?xml version="1.0" encoding="utf-8"?>
<locale xmlns="http://purl.org/net/xbiblio/csl" version="1.0" xml:lang="en-US">
<!-- The abbreviations in this file follow the recommendations of The Chicago Manual of Style, 18th ed. (2024), sec. 10.48 (cited hereafter as CMOS), unless stated otherwise. -->
<!-- Additional abbreviations are from:
1. Oxford Dictionary for Writers and Editors (2000), https://archive.org/details/oxfordstylemanua0000unse (cited hereafter as ODWE): reference has also been made to the New Oxford Dictionary for Writers and Editors (NODWE), but periods must be added to contractions in these later editions to reflect US English usage
2. Oxford Dictionary of Abbreviations (2011), https://doi.org/10.1093/acref/9780199698295.001.0001 (cited hereafter as ODA)
-->
<info>
<translator>
<name>Andrew Dunning</name>
<uri>https://orcid.org/0000-0003-0464-5036</uri>
</translator>
<translator>
<name>Sebastian Karcher</name>
<uri>https://orcid.org/0000-0001-8249-7388</uri>
</translator>
<translator>
<name>Rintze M. Zelle</name>
<uri>https://orcid.org/0000-0003-1779-8883</uri>
</translator>
<translator>
<name>Denis Meier</name>
</translator>
<translator>
<name>Brenton M. Wiernik</name>
<uri>https://orcid.org/0000-0001-9560-6336</uri>
</translator>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
<updated>2026-01-10T00:00:00+00:00</updated>
</info>
<style-options punctuation-in-quote="true"/>
<date form="text">
<date-part name="month" suffix=" "/>
<date-part name="day" suffix=", "/>
<date-part name="year"/>
</date>
<date form="numeric">
<date-part name="month" form="numeric-leading-zeros" suffix="/"/>
<date-part name="day" form="numeric-leading-zeros" suffix="/"/>
<date-part name="year"/>
</date>
<terms>
<!-- LONG GENERAL TERMS -->
<term name="accessed">accessed</term>
<term name="advance-online-publication">advance online publication</term>
<term name="album">album</term>
<term name="and">and</term>
<term name="and others">and others</term>
<term name="anonymous">anonymous</term>
<term name="at">at</term>
<term name="audio-recording">audio recording</term>
<term name="available at">available at</term>
<term name="by">by</term>
<term name="circa">circa</term>
<term name="cited">cited</term>
<term name="et-al">et al.</term>
<term name="film">film</term>
<term name="forthcoming">forthcoming</term>
<term name="from">from</term>
<term name="henceforth">henceforth</term>
<term name="ibid">ibid.</term>
<term name="in">in</term>
<term name="in press">in press</term>
<term name="internet">internet</term>
<term name="letter">letter</term>
<term name="loc-cit">loc. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
<term name="no date">no date</term>
<term name="no-place">no place</term>
<term name="no-publisher">no publisher</term>
<term name="on">on</term>
<term name="online">online</term>
<term name="op-cit">op. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
<term name="original-work-published">original work published</term>
<term name="personal-communication">personal communication</term>
<term name="podcast">podcast</term>
<term name="podcast-episode">podcast episode</term>
<term name="preprint">preprint</term>
<term name="presented at">presented at the</term>
<term name="radio-broadcast">radio broadcast</term>
<term name="radio-series">radio series</term>
<term name="radio-series-episode">radio series episode</term>
<term name="reference">
<single>reference</single>
<multiple>references</multiple>
</term>
<term name="retrieved">retrieved</term>
<term name="review-of">review of</term>
<term name="scale">scale</term>
<term name="special-issue">special issue</term>
<term name="special-section">special section</term>
<term name="television-broadcast">television broadcast</term>
<term name="television-series">television series</term>
<term name="television-series-episode">television series episode</term>
<term name="video">video</term>
<term name="working-paper">working paper</term>
<!-- SHORT GENERAL TERMS -->
<!-- Omitted short forms: accessed, album, and (symbol), and others, at (symbol), forthcoming, henceforth, ibid, in, in press, internet, loc-cit, on, online, op-cit, podcast, preprint, presented at -->
<term name="advance-online-publication" form="short">adv. online pub.</term> <!-- ODA -->
<term name="anonymous" form="short">anon.</term>
<term name="audio-recording" form="short">au. rec.</term> <!-- ODA -->
<term name="available at" form="short">avail. at</term> <!-- ODA -->
<term name="circa" form="short">c.</term>
<!-- CMOS 10.48 recommends "ca." for "circa" but also allows "c.", which CSL has used historically -->
<term name="cited" form="short">cit.</term> <!-- ODA -->
<term name="film" form="short">flm.</term> <!-- ODA -->
<term name="from" form="short">fr.</term>
<term name="letter" form="short">let.</term> <!-- ODA -->
<term name="no date" form="short">n.d.</term>
<term name="no-place" form="short">n.p.</term>
<term name="no-publisher" form="short">n.p.</term>
<term name="original-work-published" form="short">orig. pub.</term> <!-- Oxford Guide to Style -->
<term name="personal-communication" form="short">pers. comm.</term>
<term name="podcast-episode" form="short">podcast ep.</term>
<term name="radio-broadcast" form="short">radio bdcst.</term> <!-- ODA -->
<term name="radio-series" form="short">radio ser.</term> <!-- ODA -->
<term name="radio-series-episode" form="short">radio ser. ep.</term> <!-- ODA -->
<term name="reference" form="short">
<single>ref.</single>
<multiple>refs.</multiple>
</term>
<term name="retrieved" form="short">rtvd.</term> <!-- ODA -->
<term name="review-of" form="short">rev. of</term>
<term name="scale" form="short">sc.</term> <!-- ODA -->
<term name="special-issue" form="short">spec. iss.</term> <!-- ODA -->
<term name="special-section" form="short">spec. sec.</term> <!-- ODA/CMOS -->
<term name="television-broadcast" form="short">TV bdcst.</term> <!-- ODA -->
<term name="television-series" form="short">TV ser.</term> <!-- ODA -->
<term name="television-series-episode" form="short">TV ser. ep.</term> <!-- ODA -->
<term name="video" form="short">vid.</term> <!-- ODA -->
<term name="working-paper" form="short">wkg. paper</term> <!-- ODA -->
<!-- SYMBOLIC GENERAL FORMS -->
<term name="and" form="symbol">&amp;</term>
<term name="at" form="symbol">@</term>
<!-- LONG ITEM TYPE FORMS -->
<term name="article">preprint</term>
<term name="article-journal">journal article</term>
<term name="article-magazine">magazine article</term>
<term name="article-newspaper">newspaper article</term>
<term name="bill">bill</term>
<!-- book is in the list of locator terms -->
<term name="broadcast">broadcast</term>
<!-- chapter is in the list of locator terms -->
<term name="classic">classical work</term>
<term name="collection">archival collection</term>
<term name="dataset">dataset</term>
<term name="document">document</term>
<term name="entry">entry</term>
<term name="entry-dictionary">dictionary entry</term>
<term name="entry-encyclopedia">encyclopedia entry</term>
<term name="event">event</term>
<!-- figure is in the list of locator terms -->
<term name="graphic">graphic</term>
<term name="hearing">hearing</term>
<term name="interview">interview</term>
<term name="legal_case">legal case</term>
<term name="legislation">legislation</term>
<term name="manuscript">manuscript</term>
<term name="map">map</term>
<term name="motion_picture">video recording</term>
<term name="musical_score">musical score</term>
<term name="pamphlet">pamphlet</term>
<term name="paper-conference">conference paper</term>
<term name="patent">patent</term>
<term name="performance">performance</term>
<term name="periodical">periodical</term>
<term name="personal_communication">personal communication</term>
<term name="post">post</term>
<term name="post-weblog">blog post</term>
<term name="regulation">regulation</term>
<term name="report">report</term>
<term name="review">review</term>
<term name="review-book">book review</term>
<term name="software">software</term>
<term name="song">audio recording</term>
<term name="speech">presentation</term>
<term name="standard">standard</term>
<term name="thesis">thesis</term>
<term name="treaty">treaty</term>
<term name="webpage">webpage</term>
<!-- SHORT ITEM TYPE FORMS -->
<!-- Omitted short forms: article, bill, entry, event, hearing, map, periodical, speech, treaty -->
<term name="article-journal" form="short">jour. art.</term> <!-- ODWE -->
<term name="article-magazine" form="short">mag. art.</term> <!-- ODWE -->
<term name="article-newspaper" form="short">newspaper art.</term>
<term name="broadcast" form="short">bdcst.</term> <!-- ODA -->
<!-- book is in the list of locator terms -->
<!-- chapter is in the list of locator terms -->
<term name="classic" form="short">class. wk.</term> <!-- ODWE -->
<term name="collection" form="short">arch. coll.</term> <!-- ODA -->
<term name="document" form="short">doc.</term>
<term name="entry-dictionary" form="short">dict. entry</term>
<term name="entry-encyclopedia" form="short">ency. entry</term>
<!-- figure is in the list of locator terms -->
<term name="graphic" form="short">gr.</term> <!-- ODA -->
<term name="interview" form="short">int.</term> <!-- ODA -->
<term name="legal_case" form="short">leg. case</term> <!-- ODA -->
<term name="legislation" form="short">legis.</term> <!-- ODA -->
<term name="manuscript" form="short">
<single>MS</single>
<multiple>MSS</multiple>
</term>
<term name="motion_picture" form="short">vid. rec.</term> <!-- ODA -->
<term name="musical_score" form="short">mus. score</term> <!-- ODWE -->
<term name="pamphlet" form="short">pam.</term> <!-- ODWE -->
<term name="paper-conference" form="short">conf. paper</term> <!-- ODA -->
<term name="patent" form="short">pat.</term> <!-- ODWE -->
<term name="performance" form="short">prfm.</term> <!-- ODA -->
<term name="personal_communication" form="short">pers. comm.</term>
<term name="regulation" form="short">reg.</term> <!-- ODA -->
<term name="report" form="short">rep.</term> <!-- ODWE -->
<term name="review" form="short">rev.</term>
<term name="review-book" form="short">bk. rev.</term>
<term name="software" form="short">sftw.</term> <!-- ODA -->
<term name="song" form="short">au. rec.</term> <!-- ODA -->
<term name="standard" form="short">std.</term> <!-- ODA -->
<term name="thesis" form="short">thes.</term> <!-- ODA -->
<term name="webpage" form="short">webpg.</term> <!-- ODA -->
<!-- LONG VERB ITEM TYPE FORMS -->
<!-- Only where applicable -->
<term name="hearing" form="verb">testimony of</term>
<term name="review" form="verb">review of</term>
<term name="review-book" form="verb">review of the book</term>
<!-- SHORT VERB ITEM TYPE FORMS -->
<!-- Only where applicable -->
<term name="hearing" form="verb-short">test. of</term> <!-- ODA -->
<term name="review" form="verb-short">rev. of</term>
<term name="review-book" form="verb-short">rev. of the bk.</term>
<!-- HISTORICAL ERA TERMS -->
<term name="ad"> AD</term>
<term name="bc"> BC</term>
<term name="bce"> BCE</term>
<term name="ce"> CE</term>
<!-- PUNCTUATION -->
<term name="open-quote"></term>
<term name="close-quote"></term>
<term name="open-inner-quote"></term>
<term name="close-inner-quote"></term>
<term name="page-range-delimiter"></term>
<term name="colon">:</term>
<term name="comma">,</term>
<term name="semicolon">;</term>
<!-- ORDINALS -->
<term name="ordinal">th</term>
<term name="ordinal-01">st</term>
<term name="ordinal-02">nd</term>
<term name="ordinal-03">rd</term>
<term name="ordinal-11">th</term>
<term name="ordinal-12">th</term>
<term name="ordinal-13">th</term>
<!-- LONG ORDINALS -->
<term name="long-ordinal-01">first</term>
<term name="long-ordinal-02">second</term>
<term name="long-ordinal-03">third</term>
<term name="long-ordinal-04">fourth</term>
<term name="long-ordinal-05">fifth</term>
<term name="long-ordinal-06">sixth</term>
<term name="long-ordinal-07">seventh</term>
<term name="long-ordinal-08">eighth</term>
<term name="long-ordinal-09">ninth</term>
<term name="long-ordinal-10">tenth</term>
<!-- LONG LOCATOR FORMS -->
<term name="act">
<single>act</single>
<multiple>acts</multiple>
</term>
<term name="appendix">
<single>appendix</single>
<multiple>appendices</multiple>
</term>
<term name="article-locator">
<single>article</single>
<multiple>articles</multiple>
</term>
<term name="book">
<single>book</single>
<multiple>books</multiple>
</term>
<term name="canon">
<single>canon</single>
<multiple>canons</multiple>
</term>
<term name="chapter">
<single>chapter</single>
<multiple>chapters</multiple>
</term>
<term name="column">
<single>column</single>
<multiple>columns</multiple>
</term>
<term name="elocation">
<single>location</single>
<multiple>locations</multiple>
</term>
<term name="equation">
<single>equation</single>
<multiple>equations</multiple>
</term>
<term name="figure">
<single>figure</single>
<multiple>figures</multiple>
</term>
<term name="folio">
<single>folio</single>
<multiple>folios</multiple>
</term>
<term name="issue">
<single>issue</single>
<multiple>issues</multiple>
</term>
<term name="line">
<single>line</single>
<multiple>lines</multiple>
</term>
<term name="note">
<single>note</single>
<multiple>notes</multiple>
</term>
<term name="opus">
<single>opus</single>
<multiple>opera</multiple>
</term>
<term name="page">
<single>page</single>
<multiple>pages</multiple>
</term>
<term name="paragraph">
<single>paragraph</single>
<multiple>paragraphs</multiple>
</term>
<term name="part">
<single>part</single>
<multiple>parts</multiple>
</term>
<term name="rule">
<single>rule</single>
<multiple>rules</multiple>
</term>
<term name="scene">
<single>scene</single>
<multiple>scenes</multiple>
</term>
<term name="section">
<single>section</single>
<multiple>sections</multiple>
</term>
<term name="sub-verbo">
<single>sub verbo</single>
<multiple>sub verbis</multiple>
</term>
<term name="supplement">
<single>supplement</single>
<multiple>supplements</multiple>
</term>
<term name="table">
<single>table</single>
<multiple>tables</multiple>
</term>
<!-- A timestamp is a composite of hours, minutes, etc. and therefore has no default label. -->
<term name="timestamp"/>
<term name="title-locator">
<single>title</single>
<multiple>titles</multiple>
</term>
<term name="verse">
<single>verse</single>
<multiple>verses</multiple>
</term>
<term name="volume">
<single>volume</single>
<multiple>volumes</multiple>
</term>
<!-- SHORT LOCATOR FORMS -->
<!-- Omitted short forms: act, timestamp -->
<term name="appendix" form="short">
<single>app.</single>
<multiple>apps.</multiple>
</term>
<term name="article-locator" form="short">
<single>art.</single>
<multiple>arts.</multiple>
</term>
<term name="book" form="short">
<single>bk.</single>
<multiple>bks.</multiple>
</term>
<term name="canon" form="short">
<!-- Oxford Dictionary for Writers and Editors -->
<single>can.</single>
<multiple>cann.</multiple>
</term>
<term name="chapter" form="short">
<single>chap.</single>
<multiple>chaps.</multiple>
</term>
<term name="column" form="short">
<single>col.</single>
<multiple>cols.</multiple>
</term>
<term name="elocation" form="short">
<single>loc.</single>
<multiple>locs.</multiple>
</term>
<term name="equation" form="short">
<single>eq.</single>
<multiple>eqq.</multiple>
</term>
<term name="figure" form="short">
<single>fig.</single>
<multiple>figs.</multiple>
</term>
<term name="folio" form="short">
<single>fol.</single>
<multiple>fols.</multiple>
</term>
<term name="issue" form="short">
<single>no.</single>
<multiple>nos.</multiple>
</term>
<term name="line" form="short">
<single>l.</single>
<multiple>ll.</multiple>
</term>
<term name="note" form="short">
<single>n.</single>
<multiple>nn.</multiple>
</term>
<term name="opus" form="short">
<single>op.</single>
<multiple>opp.</multiple>
</term>
<term name="page" form="short">
<single>p.</single>
<multiple>pp.</multiple>
</term>
<term name="paragraph" form="short">
<single>para.</single>
<multiple>paras.</multiple>
</term>
<term name="part" form="short">
<single>pt.</single>
<multiple>pts.</multiple>
</term>
<term name="rule" form="short">
<!-- legal abbreviations in the Oxford Guide to Style, sec. 13.2.1 -->
<single>r.</single>
<multiple>rr.</multiple>
</term>
<term name="scene" form="short">
<single>sc.</single>
<multiple>scs.</multiple>
</term>
<term name="section" form="short">
<single>sec.</single>
<multiple>secs.</multiple>
</term>
<term name="sub-verbo" form="short">
<single>s.v.</single>
<multiple>s.vv.</multiple>
</term>
<term name="supplement" form="short">
<single>supp.</single>
<multiple>supps.</multiple>
</term>
<term name="table" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>tbl.</single>
<multiple>tbls.</multiple>
</term>
<term name="title-locator" form="short">
<!-- Oxford Dictionary for Writers and Editors -->
<single>tit.</single>
<multiple>titt.</multiple>
</term>
<term name="verse" form="short">
<single>v.</single>
<multiple>vv.</multiple>
</term>
<term name="volume" form="short">
<single>vol.</single>
<multiple>vols.</multiple>
</term>
<!-- SYMBOLIC LOCATOR FORMS -->
<term name="chapter" form="symbol">
<!-- caput/capita, esp. in legal works; cf. CMOS 14.196 -->
<single>c.</single>
<multiple>cc.</multiple>
</term>
<term name="paragraph" form="symbol">
<single></single>
<multiple>¶¶</multiple>
</term>
<term name="section" form="symbol">
<single>§</single>
<multiple>§§</multiple>
</term>
<!-- LONG NUMBER VARIABLE FORMS -->
<term name="chapter-number">
<single>chapter</single>
<multiple>chapters</multiple>
</term>
<term name="citation-number">
<single>citation</single>
<multiple>citations</multiple>
</term>
<term name="collection-number">
<single>number</single>
<multiple>numbers</multiple>
</term>
<term name="edition">
<single>edition</single>
<multiple>editions</multiple>
</term>
<term name="first-reference-note-number">
<single>note</single>
<multiple>notes</multiple>
</term>
<term name="number">
<single>number</single>
<multiple>numbers</multiple>
</term>
<term name="number-of-pages">
<single>page</single>
<multiple>pages</multiple>
</term>
<term name="number-of-volumes">
<single>volume</single>
<multiple>volumes</multiple>
</term>
<term name="page-first">
<single>page</single>
<multiple>pages</multiple>
</term>
<term name="printing">
<single>printing</single>
<multiple>printings</multiple>
</term>
<term name="version">
<single>version</single>
<multiple>versions</multiple>
</term>
<!-- SHORT NUMBER VARIABLE FORMS -->
<term name="chapter-number" form="short">
<single>chap.</single>
<multiple>chaps.</multiple>
</term>
<term name="citation-number" form="short">
<single>cit.</single>
<multiple>cits.</multiple>
</term>
<term name="collection-number" form="short">
<single>no.</single>
<multiple>nos.</multiple>
</term>
<term name="edition" form="short">
<single>ed.</single>
<multiple>eds.</multiple>
</term>
<term name="first-reference-note-number" form="short">
<single>n.</single>
<multiple>nn.</multiple>
</term>
<term name="number" form="short">
<single>no.</single>
<multiple>nos.</multiple>
</term>
<term name="number-of-pages" form="short">
<single>p.</single>
<multiple>pp.</multiple>
</term>
<term name="number-of-volumes" form="short">
<single>vol.</single>
<multiple>vols.</multiple>
</term>
<term name="page-first" form="short">
<single>p.</single>
<multiple>pp.</multiple>
</term>
<term name="printing" form="short">
<!-- Oxford Dictionary for Writers and Editors -->
<single>ptg.</single>
<multiple>ptgs.</multiple>
</term>
<term name="version" form="short">v.</term> <!-- no plural -->
<!-- LONG ROLE FORMS -->
<term name="author"/> <!-- generally blank -->
<term name="chair">
<single>chair</single>
<multiple>chairs</multiple>
</term>
<term name="collection-editor">
<single>editor</single>
<multiple>editors</multiple>
</term>
<term name="compiler">
<single>compiler</single>
<multiple>compilers</multiple>
</term>
<term name="composer"/> <!-- generally blank -->
<term name="container-author"/> <!-- generally blank -->
<term name="contributor">
<single>contributor</single>
<multiple>contributors</multiple>
</term>
<term name="curator">
<single>curator</single>
<multiple>curators</multiple>
</term>
<term name="director">
<single>director</single>
<multiple>directors</multiple>
</term>
<term name="editor">
<single>editor</single>
<multiple>editors</multiple>
</term>
<term name="editor-translator">
<single>editor &amp; translator</single>
<multiple>editors &amp; translators</multiple>
</term>
<term name="editortranslator">
<single>editor &amp; translator</single>
<multiple>editors &amp; translators</multiple>
</term>
<term name="editorial-director">
<single>editor</single>
<multiple>editors</multiple>
</term>
<term name="executive-producer">
<single>executive producer</single>
<multiple>executive producers</multiple>
</term>
<term name="guest">
<single>guest</single>
<multiple>guests</multiple>
</term>
<term name="host">
<single>host</single>
<multiple>hosts</multiple>
</term>
<term name="illustrator">
<single>illustrator</single>
<multiple>illustrators</multiple>
</term>
<term name="interviewer"/> <!-- generally blank -->
<term name="narrator">
<single>narrator</single>
<multiple>narrators</multiple>
</term>
<term name="organizer">
<single>organizer</single>
<multiple>organizers</multiple>
</term>
<term name="original-author"/> <!-- generally blank -->
<term name="performer">
<single>performer</single>
<multiple>performers</multiple>
</term>
<term name="producer">
<single>producer</single>
<multiple>producers</multiple>
</term>
<term name="recipient"/> <!-- generally blank -->
<term name="reviewed-author"/> <!-- generally blank -->
<term name="script-writer">
<single>writer</single>
<multiple>writers</multiple>
</term>
<term name="series-creator">
<single>series creator</single>
<multiple>series creators</multiple>
</term>
<term name="translator">
<single>translator</single>
<multiple>translators</multiple>
</term>
<!-- SHORT ROLE FORMS -->
<!-- Omitted roles:
author, chair, composer, container-author, guest, host, interviewer, original-author, recipient, reviewed-author
-->
<term name="collection-editor" form="short">
<single>ed.</single>
<multiple>eds.</multiple>
</term>
<term name="compiler" form="short">
<single>comp.</single>
<multiple>comps.</multiple>
</term>
<term name="contributor" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>contrib.</single>
<multiple>contribs.</multiple>
</term>
<term name="curator" form="short">
<!-- Oxford Art Online <https://www.oxfordartonline.com/page/1661> -->
<single>cur.</single>
<multiple>curs.</multiple>
</term>
<term name="director" form="short">
<single>dir.</single>
<multiple>dirs.</multiple>
</term>
<term name="editor" form="short">
<single>ed.</single>
<multiple>eds.</multiple>
</term>
<term name="editor-translator" form="short">
<single>ed. &amp; trans.</single>
<multiple>eds. &amp; trans.</multiple>
</term>
<term name="editortranslator" form="short">
<single>ed. &amp; trans.</single>
<multiple>eds. &amp; trans.</multiple>
</term>
<term name="editorial-director" form="short">
<single>ed.</single>
<multiple>eds.</multiple>
</term>
<term name="executive-producer" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>exec. prod.</single>
<multiple>exec. prods.</multiple>
</term>
<term name="illustrator" form="short">
<single>ill.</single>
<multiple>ills.</multiple>
</term>
<term name="narrator" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>narr.</single>
<multiple>narrs.</multiple>
</term>
<term name="organizer" form="short">
<!-- possibly misleading: Oxford Dictionary of Abbreviations only defines this as organization or organized -->
<single>org.</single>
<multiple>orgs.</multiple>
</term>
<term name="performer" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>perf.</single>
<multiple>perfs.</multiple>
</term>
<term name="producer" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>prod.</single>
<multiple>prods.</multiple>
</term>
<term name="script-writer" form="short">
<!-- Oxford Dictionary of Abbreviations -->
<single>wrtr.</single>
<multiple>wrtrs.</multiple>
</term>
<term name="series-creator" form="short">
<single>ser. creator</single>
<multiple>ser. creators</multiple>
</term>
<term name="translator" form="short">trans.</term> <!-- no plural -->
<!-- VERB ROLE FORMS -->
<term name="chair" form="verb">chaired by</term>
<term name="collection-editor" form="verb">edited by</term>
<term name="compiler" form="verb">compiled by</term>
<term name="composer" form="verb">composed by</term>
<term name="container-author" form="verb">by</term>
<term name="contributor" form="verb">with</term>
<term name="curator" form="verb">curated by</term>
<term name="director" form="verb">directed by</term>
<term name="editor" form="verb">edited by</term>
<term name="editor-translator" form="verb">edited &amp; translated by</term>
<term name="editortranslator" form="verb">edited &amp; translated by</term>
<term name="editorial-director" form="verb">edited by</term>
<term name="executive-producer" form="verb">executive produced by</term>
<term form="verb" name="guest">
<single>with guest</single>
<multiple>with guests</multiple>
</term>
<term name="host" form="verb">hosted by</term>
<term name="illustrator" form="verb">illustrated by</term>
<term name="interviewer" form="verb">interview by</term>
<term name="narrator" form="verb">narrated by</term>
<term name="organizer" form="verb">organized by</term>
<term name="original-author" form="verb">by</term>
<term name="performer" form="verb">performed by</term>
<term name="producer" form="verb">produced by</term>
<term name="recipient" form="verb">to</term>
<term name="reviewed-author" form="verb">by</term>
<term name="script-writer" form="verb">written by</term>
<term name="series-creator" form="verb">created by</term>
<term name="translator" form="verb">translated by</term>
<!-- SHORT VERB ROLE FORMS -->
<!-- Omitted roles:
author, chair, container-author, contributor, guest, host, interviewer, original-author, recipient, reviewed-author, series-creator
-->
<term name="collection-editor" form="verb-short">ed. by</term>
<term name="compiler" form="verb-short">comp. by</term>
<term name="composer" form="verb-short">comp. by</term> <!-- ODWE -->
<term name="curator" form="verb-short">cur. by</term> <!-- Oxford Art Online -->
<term name="director" form="verb-short">dir. by</term>
<term name="editor" form="verb-short">ed. by</term>
<term name="editor-translator" form="verb-short">ed. &amp; trans. by</term>
<term name="editortranslator" form="verb-short">ed. &amp; trans. by</term>
<term name="editorial-director" form="verb-short">ed. by</term>
<term name="executive-producer" form="verb-short">exec. prod. by</term> <!-- ODA -->
<term name="illustrator" form="verb-short">ill. by</term>
<term name="narrator" form="verb-short">narr. by</term> <!-- ODA -->
<term name="organizer" form="verb-short">org. by</term> <!-- ODA -->
<term name="performer" form="verb-short">perf. by</term> <!-- ODA -->
<term name="producer" form="verb-short">prod. by</term> <!-- ODA -->
<term name="script-writer" form="verb-short">writ. by</term> <!-- ODA -->
<term name="translator" form="verb-short">trans. by</term>
<!-- LONG MONTH FORMS -->
<term name="month-01">January</term>
<term name="month-02">February</term>
<term name="month-03">March</term>
<term name="month-04">April</term>
<term name="month-05">May</term>
<term name="month-06">June</term>
<term name="month-07">July</term>
<term name="month-08">August</term>
<term name="month-09">September</term>
<term name="month-10">October</term>
<term name="month-11">November</term>
<term name="month-12">December</term>
<!-- SHORT MONTH FORMS -->
<!-- Chicago Manual of Style, 18th ed., sec. 10.44 (identical to New Hart's Rules, 2nd ed., sec. 10.2.6) -->
<term name="month-01" form="short">Jan.</term>
<term name="month-02" form="short">Feb.</term>
<term name="month-03" form="short">Mar.</term>
<term name="month-04" form="short">Apr.</term>
<term name="month-05" form="short">May</term>
<term name="month-06" form="short">June</term>
<term name="month-07" form="short">July</term>
<term name="month-08" form="short">Aug.</term>
<term name="month-09" form="short">Sept.</term>
<term name="month-10" form="short">Oct.</term>
<term name="month-11" form="short">Nov.</term>
<term name="month-12" form="short">Dec.</term>
<!-- SEASONS -->
<term name="season-01">Spring</term>
<term name="season-02">Summer</term>
<term name="season-03">Autumn</term>
<term name="season-04">Winter</term>
</terms>
</locale>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
[
]

View file

@ -0,0 +1,11 @@
[
{"id":"abdillIntegration168000Samples2025","abstract":"The factors shaping human microbiome variation are a major focus of biomedical research. While other fields have used large sequencing compendia to extract insights requiring otherwise impractical sample sizes, the microbiome field has lacked a comparably sized resource for the 16S rRNA gene amplicon sequencing commonly used to quantify microbiome composition. To address this gap, we processed 168,464 publicly available human gut microbiome samples with a uniform pipeline. We use this compendium to evaluate geographic and technical effects on microbiome variation. We find that regions such as Central and Southern Asia differ significantly from the more thoroughly characterized microbiomes of Europe and Northern America and that composition alone can be used to predict a samples region of origin. We also find strong associations between microbiome variation and technical factors such as primers and DNA extraction. We anticipate this growing work, the Human Microbiome Compendium, will enable advanced applied and methodological research.","accessed":{"date-parts":[["2025",5,5]]},"author":[{"family":"Abdill","given":"Richard J."},{"family":"Graham","given":"Samantha P."},{"family":"Rubinetti","given":"Vincent"},{"family":"Ahmadian","given":"Mansooreh"},{"family":"Hicks","given":"Parker"},{"family":"Chetty","given":"Ashwin"},{"family":"McDonald","given":"Daniel"},{"family":"Ferretti","given":"Pamela"},{"family":"Gibbons","given":"Elizabeth"},{"family":"Rossi","given":"Marco"},{"family":"Krishnan","given":"Arjun"},{"family":"Albert","given":"Frank W."},{"family":"Greene","given":"Casey S."},{"family":"Davis","given":"Sean"},{"family":"Blekhman","given":"Ran"}],"citation-key":"abdillIntegration168000Samples2025","container-title":"Cell","container-title-short":"Cell","DOI":"10.1016/j.cell.2024.12.017","ISSN":"0092-8674","issue":"4","issued":{"date-parts":[["2025",2,20]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T13:59:51.848Z","page":"1100-1118.e17","source":"ScienceDirect","title":"Integration of 168,000 samples reveals global patterns of the human gut microbiome","type":"article-journal","URL":"https://www.sciencedirect.com/science/article/pii/S0092867424014302","volume":"188"},
{"id":"aitchisonConciseGuideCompositional","author":[{"family":"Aitchison","given":"John"}],"citation-key":"aitchisonConciseGuideCompositional","language":"en","source":"Zotero","title":"A Concise Guide to Compositional Data Analysis","type":"article-journal"},
{"id":"bashanUniversalityHumanMicrobial2016","abstract":"The recent realization that human-associated microbial communities play a crucial role in determining our health and well-being, has led to the ongoing development of microbiome-based therapies such as fecal microbiota transplantation,. Thosemicrobial communities are very complex, dynamic and highly personalized ecosystems,, exhibiting a high degree of inter-individual variability in both species assemblages and abundance profiles. It is not known whether the underlying ecological dynamics, which can be parameterized by growth rates, intra- and inter-species interactions in population dynamics models, are largely host-independent (i.e. “universal”) or host-specific. If the inter-individual variability reflects host-specific dynamics due to differences in host lifestyle, physiology, or genetics, then generic microbiome manipulations may have unintended consequences, rendering them ineffectual or even detrimental. Alternatively, microbial ecosystems of different subjects may follow a universal dynamics with the inter-individual variability mainly stemming from differences in the sets of colonizing species,. Here we developed a novel computational method to characterize human microbial dynamics. Applying this method to cross-sectional data from two large-scale metagenomic studies, the Human Microbiome Project, and the Student Microbiome Project, we found that both gut and mouth microbiomes display pronounced universal dynamics, whereas communities associated with certain skin sites are likely shaped by differences in the host environment. Interestingly, the universality of gut microbial dynamics is not observed in subjects with recurrent Clostridium difficile infection but is observed in the same set of subjects after fecal microbiota transplantation. These results fundamentally improve our understanding of forces and processes shaping human microbial ecosystems, paving the way to design general microbiome-based therapies.","accessed":{"date-parts":[["2025",5,5]]},"author":[{"family":"Bashan","given":"Amir"},{"family":"Gibson","given":"Travis E."},{"family":"Friedman","given":"Jonathan"},{"family":"Carey","given":"Vincent J."},{"family":"Weiss","given":"Scott T."},{"family":"Hohmann","given":"Elizabeth L."},{"family":"Liu","given":"Yang-Yu"}],"citation-key":"bashanUniversalityHumanMicrobial2016","container-title":"Nature","container-title-short":"Nature","DOI":"10.1038/nature18301","ISSN":"0028-0836","issue":"7606","issued":{"date-parts":[["2016",6,8]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T13:59:51.849Z","page":"259262","PMCID":"PMC4902290","PMID":"27279224","source":"PubMed Central","title":"Universality of Human Microbial Dynamics","type":"article-journal","URL":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4902290/","volume":"534"},
{"id":"faustOpenChallengesMicrobial2021","abstract":"Microbial network construction is a popular explorative data analysis technique in microbiome research. Although a large number of microbial network construction tools has been developed to date, there are several issues concerning the construction and interpretation of microbial networks that have received less attention. The purpose of this perspective is to draw attention to these underexplored challenges of microbial network construction and analysis.","accessed":{"date-parts":[["2025",5,5]]},"author":[{"family":"Faust","given":"Karoline"}],"citation-key":"faustOpenChallengesMicrobial2021","container-title":"The ISME Journal","container-title-short":"The ISME Journal","DOI":"10.1038/s41396-021-01027-4","ISSN":"1751-7362","issue":"11","issued":{"date-parts":[["2021",11,1]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T13:59:51.849Z","page":"31113118","source":"Silverchair","title":"Open challenges for microbial network construction and analysis","type":"article-journal","URL":"https://doi.org/10.1038/s41396-021-01027-4","volume":"15"},
{"id":"gusevaDiversityComplexityMicrobial2022","abstract":"Network analysis has been used for many years in ecological research to analyze organismal associations, for example in food webs, plant-plant or plant-animal interactions. Although network analysis is widely applied in microbial ecology, only recently has it entered the realms of soil microbial ecology, shown by a rapid rise in studies applying co-occurrence analysis to soil microbial communities. While this application offers great potential for deeper insights into the ecological structure of soil microbial ecosystems, it also brings new challenges related to the specific characteristics of soil datasets and the type of ecological questions that can be addressed. In this Perspectives Paper we assess the challenges of applying network analysis to soil microbial ecology due to the small-scale heterogeneity of the soil environment and the nature of soil microbial datasets. We review the different approaches of network construction that are commonly applied to soil microbial datasets and discuss their features and limitations. Using a test dataset of microbial communities from two depths of a forest soil, we demonstrate how different experimental designs and network constructing algorithms affect the structure of the resulting networks, and how this in turn may influence ecological conclusions. We will also reveal how assumptions of the construction method, methods of preparing the dataset, and definitions of thresholds affect the network structure. Finally, we discuss the particular questions in soil microbial ecology that can be approached by analyzing and interpreting specific network properties. Targeting these network properties in a meaningful way will allow applying this technique not in merely descriptive, but in hypothesis-driven research. Analysing microbial networks in soils opens a window to a better understanding of the complexity of microbial communities. However, this approach is unfortunately often used to draw conclusions which are far beyond the scientific evidence it can provide, which has damaged its reputation for soil microbial analysis. In this Perspectives Paper, we would like to sharpen the view for the real potential of microbial co-occurrence analysis in soils, and at the same time raise awareness regarding its limitations and the many ways how it can be misused or misinterpreted.","accessed":{"date-parts":[["2025",5,6]]},"author":[{"family":"Guseva","given":"Ksenia"},{"family":"Darcy","given":"Sean"},{"family":"Simon","given":"Eva"},{"family":"Alteio","given":"Lauren V."},{"family":"Montesinos-Navarro","given":"Alicia"},{"family":"Kaiser","given":"Christina"}],"citation-key":"gusevaDiversityComplexityMicrobial2022","container-title":"Soil Biology and Biochemistry","container-title-short":"Soil Biology and Biochemistry","DOI":"10.1016/j.soilbio.2022.108604","ISSN":"0038-0717","issued":{"date-parts":[["2022",6,1]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T14:00:11.153Z","page":"108604","source":"ScienceDirect","title":"From diversity to complexity: Microbial networks in soils","title-short":"From diversity to complexity","type":"article-journal","URL":"https://www.sciencedirect.com/science/article/pii/S003807172200061X","volume":"169"},
{"id":"heNetworkMappingRoot2021","abstract":"Understanding how plants interact with their colonizing microbiota to determine plant phenotypes is a fundamental question in modern plant science. Existing approaches for genome-wide association studies (GWAS) are often focused on the association analysis between host genes and the abundance of individual microbes, failing to characterize the genetic bases of microbial interactions that are thought to be important for microbiota structure, organization, and function. Here, we implement a behavioral model to quantify various patterns of microbe-microbe interactions, i.e., mutualism, antagonism, aggression, and altruism, and map host genes that modulate microbial networks constituted by these interaction types. We reanalyze a root-microbiome data involving 179 accessions of Arabidopsis thaliana and find that the four networks differ structurally in the pattern of bacterial-fungal interactions and microbiome complexity. We identify several fungus and bacterial hubs that play a central role in mediating microbial community assembly surrounding A. thaliana root systems. We detect 1142 significant host genetic variants throughout the plant genome and then implement Bayesian networks (BN) to reconstruct epistatic networks involving all significant SNPs, of which 91 are identified as hub QTLs. Results from gene annotation analysis suggest that most of the hub QTLs detected are in proximity to candidate genes, executing a variety of biological functions in plant growth and development, resilience against pathogens, root development, and abiotic stress resistance. This study provides a new gateway to understand how genetic variation in host plants influences microbial communities and our results could help improve crops by harnessing soil microbes.","accessed":{"date-parts":[["2025",5,6]]},"author":[{"family":"He","given":"Xiaoqing"},{"family":"Zhang","given":"Qi"},{"family":"Li","given":"Beibei"},{"family":"Jin","given":"Yi"},{"family":"Jiang","given":"Libo"},{"family":"Wu","given":"Rongling"}],"citation-key":"heNetworkMappingRoot2021","container-title":"NPJ Biofilms and Microbiomes","container-title-short":"NPJ Biofilms Microbiomes","DOI":"10.1038/s41522-021-00241-4","ISSN":"2055-5008","issued":{"date-parts":[["2021",9,7]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T13:59:20.378Z","page":"72","PMCID":"PMC8423736","PMID":"34493731","source":"PubMed Central","title":"Network mapping of rootmicrobe interactions in Arabidopsis thaliana","type":"article-journal","URL":"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8423736/","volume":"7"},
{"id":"matchadoNetworkAnalysisMethods2021","abstract":"Microorganisms including bacteria, fungi, viruses, protists and archaea live as communities in complex and contiguous environments. They engage in numerous inter- and intra- kingdom interactions which can be inferred from microbiome profiling data. In particular, network-based approaches have proven helpful in deciphering complex microbial interaction patterns. Here we give an overview of state-of-the-art methods to infer intra-kingdom interactions ranging from simple correlation- to complex conditional dependence-based methods. We highlight common biases encountered in microbial profiles and discuss mitigation strategies employed by different tools and their trade-off with increased computational complexity. Finally, we discuss current limitations that motivate further method development to infer inter-kingdom interactions and to robustly and comprehensively characterize microbial environments in the future.","accessed":{"date-parts":[["2025",5,6]]},"author":[{"family":"Matchado","given":"Monica Steffi"},{"family":"Lauber","given":"Michael"},{"family":"Reitmeier","given":"Sandra"},{"family":"Kacprowski","given":"Tim"},{"family":"Baumbach","given":"Jan"},{"family":"Haller","given":"Dirk"},{"family":"List","given":"Markus"}],"citation-key":"matchadoNetworkAnalysisMethods2021","container-title":"Computational and Structural Biotechnology Journal","container-title-short":"Computational and Structural Biotechnology Journal","DOI":"10.1016/j.csbj.2021.05.001","ISSN":"2001-0370","issued":{"date-parts":[["2021",1,1]]},"note":"Read_Status: New\nRead_Status_Date: 2025-05-06T13:59:53.425Z","page":"26872698","source":"ScienceDirect","title":"Network analysis methods for studying microbial communities: A mini review","title-short":"Network analysis methods for studying microbial communities","type":"article-journal","URL":"https://www.sciencedirect.com/science/article/pii/S2001037021001823","volume":"19"},
{"id":"PhylogeneticLatentSpace","accessed":{"date-parts":[["2026",5,11]]},"citation-key":"PhylogeneticLatentSpace","note":"Read_Status: New\nRead_Status_Date: 2026-05-12T08:46:21.525Z","title":"Phylogenetic Latent Space Models for Network Data","type":"webpage","URL":"https://arxiv.org/html/2502.11868v2"},
{"id":"raoFederatedVariationalInference2025","abstract":"We present a one-shot, unsupervised federated learning approach for Bayesian modelbased clustering of large-scale binary and categorical datasets, motivated by the need to identify patient clusters in privacy-sensitive electronic health record (EHR) data. We introduce a principled divide-and-conquer inference procedure using variational inference with local merge and delete moves within batches of the data in parallel, followed by global merge moves across batches to find global clustering structures. We show that these merge moves require only summaries of the data in each batch, enabling federated learning across local nodes without requiring the full dataset to be shared. Empirical results on simulated and benchmark datasets demonstrate that our method performs well relative to comparator clustering algorithms. We validate the practical utility of the method by applying it to a large-scale British primary care EHR dataset to identify clusters of individuals with common patterns of co-occurring conditions (multimorbidity).","accessed":{"date-parts":[["2026",3,23]]},"author":[{"family":"Rao","given":"Jackie"},{"family":"Crowe","given":"Francesca L."},{"family":"Marshall","given":"Tom"},{"family":"Richardson","given":"Sylvia"},{"family":"Kirk","given":"Paul D. W."}],"citation-key":"raoFederatedVariationalInference2025","DOI":"10.48550/arXiv.2502.12684","issued":{"date-parts":[["2025",11,12]]},"language":"en","note":"Read_Status: New\nRead_Status_Date: 2026-03-27T14:34:39.992Z","number":"arXiv:2502.12684","publisher":"arXiv","source":"arXiv.org","title":"Federated Variational Inference for Bayesian Mixture Models","type":"article","URL":"http://arxiv.org/abs/2502.12684"}
]

View file

@ -0,0 +1,10 @@
[
{"id":"beaumontApproximateBayesianComputation2010","abstract":"In the past 10 years a statistical technique, approximate Bayesian computation (ABC), has been developed that can be used to infer parameters and choose between models in the complicated scenarios that are often considered in the environmental sciences. For example, based on gene sequence and microsatellite data, the method has been used to choose between competing models of human demographic history as well as to infer growth rates, times of divergence, and other parameters. The method fits naturally in the Bayesian inferential framework, and a brief overview is given of the key concepts. Three main approaches to ABC have been developed, and these are described and compared. Although the method arose in population genetics, ABC is increasingly used in other fields, including epidemiology, systems biology, ecology, and agent-based modeling, and many of these applications are briefly described.","accessed":{"date-parts":[["2026",5,13]]},"author":[{"family":"Beaumont","given":"Mark A."}],"citation-key":"beaumontApproximateBayesianComputation2010","container-title":"Annual Review of Ecology, Evolution, and Systematics","container-title-short":"Annu. Rev. Ecol. Evol. Syst.","DOI":"10.1146/annurev-ecolsys-102209-144621","ISSN":"1543-592X, 1545-2069","issue":"1","issued":{"date-parts":[["2010",12,1]]},"language":"en","note":"Read_Status: New\nRead_Status_Date: 2026-05-13T13:19:23.883Z","page":"379406","source":"DOI.org (Crossref)","title":"Approximate Bayesian Computation in Evolution and Ecology","type":"article-journal","URL":"https://www.annualreviews.org/doi/10.1146/annurev-ecolsys-102209-144621","volume":"41"},
{"id":"csilleryApproximateBayesianComputation","author":[{"family":"Csilléry","given":"K"},{"family":"Lemaire","given":"L"},{"family":"François","given":"O"},{"family":"Blum","given":"MGB"}],"citation-key":"csilleryApproximateBayesianComputation","language":"en","note":"Read_Status: New\nRead_Status_Date: 2026-05-05T09:10:00.661Z","source":"Zotero","title":"Approximate Bayesian Computation (ABC) in R: A Vignette","type":"article-journal"},
{"id":"csilleryApproximateBayesianComputation2010","abstract":"Understanding the forces that influence natural variation within and among populations has been a major objective of evolutionary biologists for decades. Motivated by the growth in computational power and data complexity, modern approaches to this question make intensive use of simulation methods. Approximate Bayesian Computation (ABC) is one of these methods. Here we review the foundations of ABC, its recent algorithmic developments, and its applications in evolutionary biology and ecology. We argue that the use of ABC should incorporate all aspects of Bayesian data analysis: formulation, fitting, and improvement of a model. ABC can be a powerful tool to make inferences with complex models if these principles are carefully applied.","author":[{"family":"Csilléry","given":"Katalin"},{"family":"Blum","given":"Michael G. B."},{"family":"Gaggiotti","given":"Oscar E."},{"family":"François","given":"Olivier"}],"citation-key":"csilleryApproximateBayesianComputation2010","container-title":"Trends in Ecology & Evolution","container-title-short":"Trends Ecol Evol","DOI":"10.1016/j.tree.2010.04.001","ISSN":"0169-5347","issue":"7","issued":{"date-parts":[["2010",7]]},"language":"eng","note":"Read_Status: New\nRead_Status_Date: 2026-04-07T13:22:11.099Z","page":"410418","PMID":"20488578","source":"PubMed","title":"Approximate Bayesian Computation (ABC) in practice","type":"article-journal","volume":"25"},
{"id":"fortes-limaComplexGeneticAdmixture2021","abstract":"Admixture is a fundamental evolutionary process that has influenced genetic patterns in numerous species. Maximum-likelihood approaches based on allele frequencies and linkage-disequilibrium have been extensively used to infer admixture processes from genome-wide data sets, mostly in human populations. Nevertheless, complex admixture histories, beyond one or two pulses of admixture, remain methodologically challenging to reconstruct. We developed an Approximate Bayesian Computation (ABC) framework to reconstruct highly complex admixture histories from independent genetic markers. We built the software package MetHis to simulate independent SNPs or microsatellites in a two-way admixed population for scenarios with multiple admixture pulses, monotonically decreasing or increasing recurring admixture, or combinations of these scenarios. MetHis allows users to draw model-parameter values from prior distributions set by the user, and, for each simulation, MetHis can calculate numerous summary statistics describing genetic diversity patterns and moments of the distribution of individual admixture fractions. We coupled MetHis with existing machine-learning ABC algorithms and investigated the admixture history of admixed populations. Results showed that random forest ABC scenario-choice could accurately distinguish among most complex admixture scenarios, and errors were mainly found in regions of the parameter space where scenarios were highly nested, and, thus, biologically similar. We focused on African American and Barbadian populations as two study-cases. We found that neural network ABC posterior parameter estimation was accurate and reasonably conservative under complex admixture scenarios. For both admixed populations, we found that monotonically decreasing contributions over time, from Europe and Africa, explained the observed data more accurately than multiple admixture pulses. This approach will allow for reconstructing detailed admixture histories when maximum-likelihood methods are intractable.","author":[{"family":"Fortes-Lima","given":"Cesar A."},{"family":"Laurent","given":"Romain"},{"family":"Thouzeau","given":"Valentin"},{"family":"Toupance","given":"Bruno"},{"family":"Verdu","given":"Paul"}],"citation-key":"fortes-limaComplexGeneticAdmixture2021","container-title":"Molecular Ecology Resources","container-title-short":"Mol Ecol Resour","DOI":"10.1111/1755-0998.13325","ISSN":"1755-0998","issue":"4","issued":{"date-parts":[["2021",5]]},"language":"eng","note":"Read_Status: New\nRead_Status_Date: 2026-04-07T13:23:36.649Z","page":"10981117","PMCID":"PMC8247995","PMID":"33452723","source":"PubMed","title":"Complex genetic admixture histories reconstructed with Approximate Bayesian Computation","type":"article-journal","volume":"21"},
{"id":"pudloReliableABCModel2016","abstract":"Motivation: Approximate Bayesian computation (ABC) methods provide an elaborate approach to Bayesian inference on complex models, including model choice. Both theoretical arguments and simulation experiments indicate, however, that model posterior probabilities may be poorly evaluated by standard ABC techniques.Results: We propose a novel approach based on a machine learning tool named random forests (RF) to conduct selection among the highly complex models covered by ABC algorithms. We thus modify the way Bayesian model selection is both understood and operated, in that we rephrase the inferential goal as a classification problem, first predicting the model that best fits the data with RF and postponing the approximation of the posterior probability of the selected model for a second stage also relying on RF. Compared with earlier implementations of ABC model choice, the ABC RF approach offers several potential improvements: (i) it often has a larger discriminative power among the competing models, (ii) it is more robust against the number and choice of statistics summarizing the data, (iii) the computing effort is drastically reduced (with a gain in computation efficiency of at least 50) and (iv) it includes an approximation of the posterior probability of the selected model. The call to RF will undoubtedly extend the range of size of datasets and complexity of models that ABC can handle. We illustrate the power of this novel methodology by analyzing controlled experiments as well as genuine population genetics datasets.Availability and implementation: The proposed methodology is implemented in the R package abcrf available on the CRAN.Contact:  jean-michel.marin@umontpellier.frSupplementary information:  Supplementary data are available at Bioinformatics online.","accessed":{"date-parts":[["2026",4,7]]},"author":[{"family":"Pudlo","given":"Pierre"},{"family":"Marin","given":"Jean-Michel"},{"family":"Estoup","given":"Arnaud"},{"family":"Cornuet","given":"Jean-Marie"},{"family":"Gautier","given":"Mathieu"},{"family":"Robert","given":"Christian P."}],"citation-key":"pudloReliableABCModel2016","container-title":"Bioinformatics","container-title-short":"Bioinformatics","DOI":"10.1093/bioinformatics/btv684","ISSN":"1367-4803","issue":"6","issued":{"date-parts":[["2016",3,15]]},"note":"Read_Status: New\nRead_Status_Date: 2026-04-07T13:23:20.640Z","page":"859866","source":"Silverchair","title":"Reliable ABC model choice via random forests","type":"article-journal","URL":"https://doi.org/10.1093/bioinformatics/btv684","volume":"32"},
{"id":"raynalABCRandomForests2019","abstract":"Approximate Bayesian computation (ABC) has grown into a standard methodology that manages Bayesian inference for models associated with intractable likelihood functions. Most ABC implementations require the preliminary selection of a vector of informative statistics summarizing raw data. Furthermore, in almost all existing implementations, the tolerance level that separates acceptance from rejection of simulated parameter values needs to be calibrated.We propose to conduct likelihood-free Bayesian inferences about parameters with no prior selection of the relevant components of the summary statistics and bypassing the derivation of the associated tolerance level. The approach relies on the random forest (RF) methodology of Breiman (2001) applied in a (non-parametric) regression setting. We advocate the derivation of a new RF for each component of the parameter vector of interest. When compared with earlier ABC solutions, this method offers significant gains in terms of robustness to the choice of the summary statistics, does not depend on any type of tolerance level, and is a good trade-off in term of quality of point estimator precision and credible interval estimations for a given computing time. We illustrate the performance of our methodological proposal and compare it with earlier ABC methods on a Normal toy example and a population genetics example dealing with human population evolution.All methods designed here have been incorporated in the R package abcrf (version 1.7.1) available on CRAN.Supplementary data are available at Bioinformatics online.","accessed":{"date-parts":[["2026",4,7]]},"author":[{"family":"Raynal","given":"Louis"},{"family":"Marin","given":"Jean-Michel"},{"family":"Pudlo","given":"Pierre"},{"family":"Ribatet","given":"Mathieu"},{"family":"Robert","given":"Christian P"},{"family":"Estoup","given":"Arnaud"}],"citation-key":"raynalABCRandomForests2019","container-title":"Bioinformatics","container-title-short":"Bioinformatics","DOI":"10.1093/bioinformatics/bty867","ISSN":"1367-4803","issue":"10","issued":{"date-parts":[["2019",5,15]]},"note":"Read_Status: New\nRead_Status_Date: 2026-04-07T13:22:59.866Z","page":"17201728","source":"Silverchair","title":"ABC random forests for Bayesian parameter inference","type":"article-journal","URL":"https://doi.org/10.1093/bioinformatics/bty867","volume":"35"},
{"id":"robertWhyApproximateBayesian","abstract":"Approximate Bayesian computation (ABC), also known as likelihood-free methods, have become a favourite tool for the analysis of complex stochastic models, primarily in population genetics but also in financial analyses. We advocated in Grelaud et al. (2009) the use of ABC for Bayesian model choice in the specific case of Gibbs random fields (GRF), relying on a sufficiency property mainly enjoyed by GRFs to show that the approach was legitimate. Despite having previously suggested the use of ABC for model choice in a wider range of models in the DIY ABC software (Cornuet et al., 2008), we present theoretical evidence that the general use of ABC for model choice is fraught with danger in the sense that no amount of computation, however large, can guarantee a proper approximation of the posterior probabilities of the models under comparison.","author":[{"family":"Robert","given":"Christian P"},{"family":"Marin","given":"Jean-Michel"},{"family":"Pillai","given":"Natesh S"}],"citation-key":"robertWhyApproximateBayesian","language":"en","note":"Read_Status: New\nRead_Status_Date: 2026-04-07T13:23:25.869Z","source":"Zotero","title":"Why approximate Bayesian computational (ABC) methods cannot handle model choice problems","type":"article-journal"},
{"id":"turnerTutorialApproximateBayesian2012","abstract":"This tutorial explains the foundation of approximate Bayesian computation (ABC), an approach to Bayesian inference that does not require the specification of a likelihood function, and hence that can be used to estimate posterior distributions of parameters for simulation-based models. We discuss briefly the philosophy of Bayesian inference and then present several algorithms for ABC. We then apply these algorithms in a number of examples. For most of these examples, the posterior distributions are known, and so we can compare the estimated posteriors derived from ABC to the true posteriors and verify that the algorithms recover the true posteriors accurately. We also consider a popular simulation-based model of recognition memory (REM) for which the true posteriors are unknown. We conclude with a number of recommendations for applying ABC methods to solve real-world problems.","accessed":{"date-parts":[["2026",5,5]]},"author":[{"family":"Turner","given":"Brandon M."},{"family":"Van Zandt","given":"Trisha"}],"citation-key":"turnerTutorialApproximateBayesian2012","container-title":"Journal of Mathematical Psychology","container-title-short":"Journal of Mathematical Psychology","DOI":"10.1016/j.jmp.2012.02.005","ISSN":"00222496","issue":"2","issued":{"date-parts":[["2012",4]]},"language":"en","license":"https://www.elsevier.com/tdm/userlicense/1.0/","note":"Read_Status: New\nRead_Status_Date: 2026-05-05T08:49:17.248Z","page":"6985","source":"DOI.org (Crossref)","title":"A tutorial on approximate Bayesian computation","type":"article-journal","URL":"https://linkinghub.elsevier.com/retrieve/pii/S0022249612000272","volume":"56"}
]

View file

@ -0,0 +1,708 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.5.57">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Note de lecture de A tutorial on approximate Bayesian computation de Brandon M. Turner, Trisha Van Zandt.</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
width: 0.8em;
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
vertical-align: middle;
}
</style>
<script src="@turnerTutorialApproximateBayesian2012_files/libs/clipboard/clipboard.min.js"></script>
<script src="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/quarto.js"></script>
<script src="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/popper.min.js"></script>
<script src="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/tippy.umd.min.js"></script>
<script src="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/anchor.min.js"></script>
<link href="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/tippy.css" rel="stylesheet">
<link href="@turnerTutorialApproximateBayesian2012_files/libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
<script src="@turnerTutorialApproximateBayesian2012_files/libs/bootstrap/bootstrap.min.js"></script>
<link href="@turnerTutorialApproximateBayesian2012_files/libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="@turnerTutorialApproximateBayesian2012_files/libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
<script type="text/javascript">
const typesetMath = (el) => {
if (window.MathJax) {
// MathJax Typeset
window.MathJax.typeset([el]);
} else if (window.katex) {
// KaTeX Render
var mathElements = el.getElementsByClassName("math");
var macros = [];
for (var i = 0; i < mathElements.length; i++) {
var texText = mathElements[i].firstChild;
if (mathElements[i].tagName == "SPAN") {
window.katex.render(texText.data, mathElements[i], {
displayMode: mathElements[i].classList.contains('display'),
throwOnError: false,
macros: macros,
fleqn: false
});
}
}
}
}
window.Quarto = {
typesetMath
};
</script>
</head>
<body class="fullcontent">
<div id="quarto-content" class="page-columns page-rows-contents page-layout-article">
<main class="content" id="quarto-document-content">
<header id="title-block-header" class="quarto-title-block default">
<div class="quarto-title">
<h1 class="title">Note de lecture de <em>A tutorial on approximate Bayesian computation</em> de Brandon M. Turner, Trisha Van Zandt.</h1>
<div class="quarto-categories">
<div class="quarto-category">literature note</div>
</div>
</div>
<div class="quarto-title-meta">
</div>
</header>
<div class="callout callout-style-default callout-note callout-titled" title="Synthèse">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Synthèse
</div>
</div>
<div class="callout-body-container callout-body">
<p><strong>Contribution</strong>:</p>
<p><strong>Related</strong>:</p>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled" title="Markdown">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Markdown
</div>
</div>
<div class="callout-body-container callout-body">
<p><strong>FirstAuthor</strong>: Turner, Brandon M.<br>
<strong>Author</strong>: Van Zandt, Trisha</p>
<p><strong>Title</strong>: A tutorial on approximate Bayesian computation<br>
<strong>Year</strong>: 2012<br>
<strong>Citekey</strong>: turnerTutorialApproximateBayesian2012<br>
<strong>itemType</strong>: journalArticle<br>
<strong>Journal</strong>: <em>Journal of Mathematical Psychology</em><br>
<strong>Volume</strong>: 56<br>
<strong>Issue</strong>: 2<br>
<strong>Pages</strong>: 69-85<br>
<strong>DOI</strong>: 10.1016/j.jmp.2012.02.005</p>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled" title="Pièces-jointes">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Pièces-jointes
</div>
</div>
<div class="callout-body-container callout-body">
<blockquote class="blockquote">
<p><a href="file:///home/louis/snap/zotero-snap/common/Zotero/storage/N4E59NBM/Turner%20et%20Van%20Zandt%20-%202012%20-%20A%20tutorial%20on%20approximate%20Bayesian%20computation.pdf">PDF</a>.</p>
</blockquote>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled" title="Abstract">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Abstract
</div>
</div>
<div class="callout-body-container callout-body">
<p>This tutorial explains the foundation of approximate Bayesian computation (ABC), an approach to Bayesian inference that does not require the specification of a likelihood function, and hence that can be used to estimate posterior distributions of parameters for simulation-based models. We discuss briefly the philosophy of Bayesian inference and then present several algorithms for ABC. We then apply these algorithms in a number of examples. For most of these examples, the posterior distributions are known, and so we can compare the estimated posteriors derived from ABC to the true posteriors and verify that the algorithms recover the true posteriors accurately. We also consider a popular simulation-based model of recognition memory (REM) for which the true posteriors are unknown. We conclude with a number of recommendations for applying ABC methods to solve real-world problems..</p>
</div>
</div>
<section id="prise-de-notes" class="level1">
<h1>Prise de notes</h1>
<p>%% begin user_notes %%</p>
<section id="introduction" class="level2">
<h2 class="anchored" data-anchor-id="introduction">Introduction</h2>
<p>La première partie est une explication du point de vue bayésien avec un regard sur les modèles en psychologie cognitive</p>
<p>Les auteurs différencie les modèles “mathématiques” : ont une vraisemblance explicite, des modèles de “simulation” : pas de vraisemblance explicite et génèrent des prédictions en répliquant/modélisant le mécanisme de génération de données</p>
</section>
<section id="approximate-bayesian-computation" class="level2">
<h2 class="anchored" data-anchor-id="approximate-bayesian-computation">Approximate Bayesian computation</h2>
<p><span class="math display">\[
\newcommand{\ts}{\theta^{\star}}
\newcommand{\tss}{\theta^{\star\star}}
\]</span></p>
<p><strong>Idée principale</strong>: Remplacer un calcul de vraisemblance coûteux (ou impossible?) par des simulations qui produisent un jeu de données artificiel <span class="math inline">\(X\)</span>.</p>
<p>Donc on cherche à simuler des jeux de données <span class="math inline">\(X\)</span> qui approchent bien <span class="math inline">\(Y\)</span> notre vrai jeu de données en utilisant diverses valeurs de <span class="math inline">\(\theta^{\star}\)</span> puis en retenant celle qui donnent <span class="math inline">\(\rho(X,Y) \leq \epsilon_{0}\)</span> avec lidée dapprocher la posterior <span class="math inline">\(\pi(\theta\mid Y)\)</span> par <span class="math inline">\(\pi(\theta\mid \rho(X,Y) \leq \epsilon_{0})\)</span></p>
<p><strong>Procédure</strong>:</p>
<ol type="1">
<li>Échantillonner <span class="math inline">\(\theta^{\star}\)</span> de la prior <span class="math inline">\(\pi(\theta)\)</span></li>
<li>Générer <span class="math inline">\(X\)</span> en utilisant <span class="math inline">\(\theta^{\star}\)</span></li>
<li>Comparer <span class="math inline">\(\rho(X,Y)\)</span> à <span class="math inline">\(\epsilon_{0}\)</span>
<ol type="a">
<li>Si <span class="math inline">\(\rho(X,Y) \leq \epsilon_{0}\)</span> alors <span class="math inline">\(\theta^{\star}\)</span> est conservé comme valeur probable de la posterior</li>
<li>Sinon on fait quelque chose avec <span class="math inline">\(\theta^{\star}\)</span>, dans lacceptation-rejet : on rejette <span class="math inline">\(\theta^{\star}\)</span></li>
</ol></li>
</ol>
<p>Pour faciliter les calculs on remplace <span class="math inline">\(X, Y\)</span> par des statistiques. Si elles sont suffisantes (limitation à la famille exponentielle) très bon remplacement sans perte dinformations.</p>
<p><em>Remarque sur Acceptation-Rejet (AR-ABC) :</em> pour <span class="math inline">\(\epsilon_{0}\)</span> très petit le taux de rejet peut être trop élevé et lalgo très inefficace.</p>
<section id="abc-mcmc" class="level3">
<h3 class="anchored" data-anchor-id="abc-mcmc">ABC MCMC</h3>
<p>Au lieu de calculer la proba dacceptation par la vraisemblance, on utilise <span class="math inline">\(\theta^{\star}\)</span> pour générer <span class="math inline">\(X\)</span> et alors la proba dacceptation est :</p>
<p><span class="math display">\[
\alpha = \begin{cases} \min(1,\frac{\pi(\theta^{\star})q(\theta_{i}\mid \theta^{\star})}{\pi(\theta_{i})q(\theta^{\star}\mid \theta_{i})}) &amp; \text{si } \rho(X,Y)\leq \epsilon_{0} \\
0 &amp; \text{sinon}
\end{cases}
\]</span></p>
<p><span class="math inline">\(q\)</span> est la loi de proposition.</p>
<p>Si elle est symétrique, les deux termes sannulent et <span class="math inline">\(\alpha\)</span> ne dépend que du prior, de la distance aux données réelles et de <span class="math inline">\(\epsilon_{0}\)</span>.</p>
<p><strong>Limites importantes</strong>:</p>
<ul>
<li>Très probable de se retrouver bloquée dans les zones de faibles probas où les <span class="math inline">\(\theta^{\star}\)</span> génèreront des <span class="math inline">\(X\)</span> improbable et donc dy rester bloqué. Et ainsi <em>fort taux de rejet</em>.</li>
<li>Pas possible de paralléliser une chaîne car dépendance.</li>
</ul>
</section>
<section id="particle-filtering-monte-carlo-séquentiel" class="level3">
<h3 class="anchored" data-anchor-id="particle-filtering-monte-carlo-séquentiel"><em>Particle filtering</em>, Monte-Carlo séquentiel</h3>
<p><strong>Principe de lalgorithme</strong>:</p>
<ol type="1">
<li>Générer une <em>pool</em> de valeurs <span class="math inline">\(\{\theta_{1}, \dots, \theta_{i}, \dots, \theta_{N}\}\)</span> selon <span class="math inline">\(\pi(\theta)\)</span></li>
<li>Initialiser les poids de sélection <span class="math inline">\(w_{i} = \frac{1}{N}\)</span></li>
<li>Itérer pour <span class="math inline">\(T\)</span> étapes :
<ol type="a">
<li>Tirer <span class="math inline">\(\theta^{*}\)</span> de la <em>pool</em> avec les poids <span class="math inline">\(\pmb{w}\)</span></li>
<li>Utiliser le noyau de transition <em>forward</em>[^1] <span class="math inline">\(q(\theta^{\star\star}|\theta^{\star})\)</span> pour proposer la nouvelle particule <span class="math inline">\(\tss\)</span></li>
<li>Mettre à jour <span class="math inline">\(\pmb{w}\)</span></li>
</ol></li>
</ol>
<p>À la fin la <em>pool</em> est (on espère) distribuée selon <span class="math inline">\(\pi(\theta\mid Y)\)</span>.</p>
<section id="partial-rejection-control-abc-prc" class="level4">
<h4 class="anchored" data-anchor-id="partial-rejection-control-abc-prc"><em>Partial Rejection control</em> : ABC PRC</h4>
<p><span class="math display">\[
\newcommand{\qf}[1]{q_{f}(#1|\ts)}
\newcommand{\qb}[1]{q_{b}(#1|\tss)}
\newcommand{\thresh}{\rho(X,Y) \leq \epsilon_{0}}
\]</span></p>
<p>Il y a besoin de deux noyaux de transition <span class="math inline">\(\qf{.},\qb{.}\)</span> forward et backward.</p>
<p>On spécifie ici létape :</p>
<ol start="2" type="a">
<li><span class="math inline">\(\tss \sim \qf{\theta_{i}}\)</span>. Si le <span class="math inline">\(X\)</span> réalisé par <span class="math inline">\(\tss\)</span> est tel que <span class="math inline">\(\rho(X,Y) \leq \epsilon_{0}\)</span> alors <span class="math inline">\(\theta_{i} = \tss\)</span>. Sinon on rejette <span class="math inline">\(\tss\)</span> et on itère jusquà passer le critère.</li>
</ol>
<p>Alors le poids de la particule est mis à jour :</p>
<p><span class="math display">\[
w = \frac{\pi(\tss)\qb{\ts}}{\pi(\ts)\qf{\tss}}
\]</span></p>
<p>Et on répète jusquà avoir remplacé nos <span class="math inline">\(N\)</span> particules afin quelles satisfassent toutes <span class="math inline">\(\thresh\)</span>.</p>
<p>Puis on ré-itère <span class="math inline">\(T\)</span> fois lopération.</p>
<p><strong>Avantages</strong>:</p>
<ul>
<li>Permet de sortir des régions de faibles probabilités en enlevant les particules. <strong>Limites</strong>:</li>
<li>Estimation biaisée de la posterior</li>
</ul>
<p><a href="zotero://select/items/1_TR63KKUN">Turner. 4/2012. <i>A tutorial on approximate Bayesian computation</i></a></p>
<p>Je rajoute dautres notes nouvelles</p>
<p>%% end user_notes %%# Annotations importées%% begin annotations %%</p>
</section>
</section>
<section id="imported-2026-05-13-205-pm" class="level3">
<h3 class="anchored" data-anchor-id="imported-2026-05-13-205-pm">Imported: 2026-05-13 2:05 pm</h3>
<p><mark style="background-color: #5fb236">Quote</mark></p>
<blockquote class="blockquote">
<p>The simplest of these is the ABC rejection sampling algorithm (see Algorithm 1; Beaumont, Zhang, &amp; Balding, 2002; Pritchard et al., 1999). The ABC rejection sampler simply discards the candidate value θ if it does not meet the criterion ρ(X , Y ) ≤ ε0, as we described above.</p>
</blockquote>
</section>
<section id="imported-2026-05-13-532-pm" class="level3">
<h3 class="anchored" data-anchor-id="imported-2026-05-13-532-pm">Imported: 2026-05-13 5:32 pm</h3>
<p><mark style="background-color: #5fb236">Quote</mark></p>
<blockquote class="blockquote">
<p>The simplest of these is the ABC rejection sampling algorithm (see Algorithm 1; Beaumont, Zhang, &amp; Balding, 2002; Pritchard et al., 1999). The ABC rejection sampler simply discards the candidate value θ if it does not meet the criterion ρ(X , Y ) ≤ ε0, as we described above.</p>
</blockquote>
</section>
<section id="imported-2026-05-13-535-pm" class="level3">
<h3 class="anchored" data-anchor-id="imported-2026-05-13-535-pm">Imported: 2026-05-13 5:35 pm</h3>
<p><mark style="background-color: #5fb236">Quote</mark></p>
<blockquote class="blockquote">
<p>If the particle does not pass inspection (if ρ(X , Y ) &gt; ε0), it is discarded</p>
</blockquote>
</section>
<section id="imported-2026-05-13-542-pm" class="level3">
<h3 class="anchored" data-anchor-id="imported-2026-05-13-542-pm">Imported: 2026-05-13 5:42 pm</h3>
<p><mark style="background-color: #5fb236">Quote</mark></p>
<blockquote class="blockquote">
<p>If the particle does not pass inspection (if ρ(X , Y ) &gt; ε0), it is discarded</p>
</blockquote>
<p>%% end annotations %%</p>
<p>%% Import Date: 2026-05-13T17:44:26.337+02:00 %%</p>
</section>
</section>
</section>
</main>
<!-- /main column -->
<script id="quarto-html-after-body" type="application/javascript">
window.document.addEventListener("DOMContentLoaded", function (event) {
const toggleBodyColorMode = (bsSheetEl) => {
const mode = bsSheetEl.getAttribute("data-mode");
const bodyEl = window.document.querySelector("body");
if (mode === "dark") {
bodyEl.classList.add("quarto-dark");
bodyEl.classList.remove("quarto-light");
} else {
bodyEl.classList.add("quarto-light");
bodyEl.classList.remove("quarto-dark");
}
}
const toggleBodyColorPrimary = () => {
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
if (bsSheetEl) {
toggleBodyColorMode(bsSheetEl);
}
}
toggleBodyColorPrimary();
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {
placement: 'right',
icon: icon
};
anchorJS.add('.anchored');
const isCodeAnnotation = (el) => {
for (const clz of el.classList) {
if (clz.startsWith('code-annotation-')) {
return true;
}
}
return false;
}
const onCopySuccess = function(e) {
// button target
const button = e.trigger;
// don't keep focus
button.blur();
// flash "checked"
button.classList.add('code-copy-button-checked');
var currentTitle = button.getAttribute("title");
button.setAttribute("title", "Copied!");
let tooltip;
if (window.bootstrap) {
button.setAttribute("data-bs-toggle", "tooltip");
button.setAttribute("data-bs-placement", "left");
button.setAttribute("data-bs-title", "Copied!");
tooltip = new bootstrap.Tooltip(button,
{ trigger: "manual",
customClass: "code-copy-button-tooltip",
offset: [0, -8]});
tooltip.show();
}
setTimeout(function() {
if (tooltip) {
tooltip.hide();
button.removeAttribute("data-bs-title");
button.removeAttribute("data-bs-toggle");
button.removeAttribute("data-bs-placement");
}
button.setAttribute("title", currentTitle);
button.classList.remove('code-copy-button-checked');
}, 1000);
// clear code selection
e.clearSelection();
}
const getTextToCopy = function(trigger) {
const codeEl = trigger.previousElementSibling.cloneNode(true);
for (const childEl of codeEl.children) {
if (isCodeAnnotation(childEl)) {
childEl.remove();
}
}
return codeEl.innerText;
}
const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
text: getTextToCopy
});
clipboard.on('success', onCopySuccess);
if (window.document.getElementById('quarto-embedded-source-code-modal')) {
// For code content inside modals, clipBoardJS needs to be initialized with a container option
// TODO: Check when it could be a function (https://github.com/zenorocha/clipboard.js/issues/860)
const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
text: getTextToCopy,
container: window.document.getElementById('quarto-embedded-source-code-modal')
});
clipboardModal.on('success', onCopySuccess);
}
var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
var mailtoRegex = new RegExp(/^mailto:/);
var filterRegex = new RegExp('/' + window.location.host + '/');
var isInternal = (href) => {
return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
}
// Inspect non-navigation links and adorn them if external
var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
for (var i=0; i<links.length; i++) {
const link = links[i];
if (!isInternal(link.href)) {
// undo the damage that might have been done by quarto-nav.js in the case of
// links that we want to consider external
if (link.dataset.originalHref !== undefined) {
link.href = link.dataset.originalHref;
}
}
}
function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
const config = {
allowHTML: true,
maxWidth: 500,
delay: 100,
arrow: false,
appendTo: function(el) {
return el.parentElement;
},
interactive: true,
interactiveBorder: 10,
theme: 'quarto',
placement: 'bottom-start',
};
if (contentFn) {
config.content = contentFn;
}
if (onTriggerFn) {
config.onTrigger = onTriggerFn;
}
if (onUntriggerFn) {
config.onUntrigger = onUntriggerFn;
}
window.tippy(el, config);
}
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
for (var i=0; i<noterefs.length; i++) {
const ref = noterefs[i];
tippyHover(ref, function() {
// use id or data attribute instead here
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
try { href = new URL(href).hash; } catch {}
const id = href.replace(/^#\/?/, "");
const note = window.document.getElementById(id);
if (note) {
return note.innerHTML;
} else {
return "";
}
});
}
const xrefs = window.document.querySelectorAll('a.quarto-xref');
const processXRef = (id, note) => {
// Strip column container classes
const stripColumnClz = (el) => {
el.classList.remove("page-full", "page-columns");
if (el.children) {
for (const child of el.children) {
stripColumnClz(child);
}
}
}
stripColumnClz(note)
if (id === null || id.startsWith('sec-')) {
// Special case sections, only their first couple elements
const container = document.createElement("div");
if (note.children && note.children.length > 2) {
container.appendChild(note.children[0].cloneNode(true));
for (let i = 1; i < note.children.length; i++) {
const child = note.children[i];
if (child.tagName === "P" && child.innerText === "") {
continue;
} else {
container.appendChild(child.cloneNode(true));
break;
}
}
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(container);
}
return container.innerHTML
} else {
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(note);
}
return note.innerHTML;
}
} else {
// Remove any anchor links if they are present
const anchorLink = note.querySelector('a.anchorjs-link');
if (anchorLink) {
anchorLink.remove();
}
if (window.Quarto?.typesetMath) {
window.Quarto.typesetMath(note);
}
// TODO in 1.5, we should make sure this works without a callout special case
if (note.classList.contains("callout")) {
return note.outerHTML;
} else {
return note.innerHTML;
}
}
}
for (var i=0; i<xrefs.length; i++) {
const xref = xrefs[i];
tippyHover(xref, undefined, function(instance) {
instance.disable();
let url = xref.getAttribute('href');
let hash = undefined;
if (url.startsWith('#')) {
hash = url;
} else {
try { hash = new URL(url).hash; } catch {}
}
if (hash) {
const id = hash.replace(/^#\/?/, "");
const note = window.document.getElementById(id);
if (note !== null) {
try {
const html = processXRef(id, note.cloneNode(true));
instance.setContent(html);
} finally {
instance.enable();
instance.show();
}
} else {
// See if we can fetch this
fetch(url.split('#')[0])
.then(res => res.text())
.then(html => {
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(html, "text/html");
const note = htmlDoc.getElementById(id);
if (note !== null) {
const html = processXRef(id, note);
instance.setContent(html);
}
}).finally(() => {
instance.enable();
instance.show();
});
}
} else {
// See if we can fetch a full url (with no hash to target)
// This is a special case and we should probably do some content thinning / targeting
fetch(url)
.then(res => res.text())
.then(html => {
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(html, "text/html");
const note = htmlDoc.querySelector('main.content');
if (note !== null) {
// This should only happen for chapter cross references
// (since there is no id in the URL)
// remove the first header
if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
note.children[0].remove();
}
const html = processXRef(null, note);
instance.setContent(html);
}
}).finally(() => {
instance.enable();
instance.show();
});
}
}, function(instance) {
});
}
let selectedAnnoteEl;
const selectorForAnnotation = ( cell, annotation) => {
let cellAttr = 'data-code-cell="' + cell + '"';
let lineAttr = 'data-code-annotation="' + annotation + '"';
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
return selector;
}
const selectCodeLines = (annoteEl) => {
const doc = window.document;
const targetCell = annoteEl.getAttribute("data-target-cell");
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
const lineIds = lines.map((line) => {
return targetCell + "-" + line;
})
let top = null;
let height = null;
let parent = null;
if (lineIds.length > 0) {
//compute the position of the single el (top and bottom and make a div)
const el = window.document.getElementById(lineIds[0]);
top = el.offsetTop;
height = el.offsetHeight;
parent = el.parentElement.parentElement;
if (lineIds.length > 1) {
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
height = bottom - top;
}
if (top !== null && height !== null && parent !== null) {
// cook up a div (if necessary) and position it
let div = window.document.getElementById("code-annotation-line-highlight");
if (div === null) {
div = window.document.createElement("div");
div.setAttribute("id", "code-annotation-line-highlight");
div.style.position = 'absolute';
parent.appendChild(div);
}
div.style.top = top - 2 + "px";
div.style.height = height + 4 + "px";
div.style.left = 0;
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
if (gutterDiv === null) {
gutterDiv = window.document.createElement("div");
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
gutterDiv.style.position = 'absolute';
const codeCell = window.document.getElementById(targetCell);
const gutter = codeCell.querySelector('.code-annotation-gutter');
gutter.appendChild(gutterDiv);
}
gutterDiv.style.top = top - 2 + "px";
gutterDiv.style.height = height + 4 + "px";
}
selectedAnnoteEl = annoteEl;
}
};
const unselectCodeLines = () => {
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
elementsIds.forEach((elId) => {
const div = window.document.getElementById(elId);
if (div) {
div.remove();
}
});
selectedAnnoteEl = undefined;
};
// Handle positioning of the toggle
window.addEventListener(
"resize",
throttle(() => {
elRect = undefined;
if (selectedAnnoteEl) {
selectCodeLines(selectedAnnoteEl);
}
}, 10)
);
function throttle(fn, ms) {
let throttle = false;
let timer;
return (...args) => {
if(!throttle) { // first call gets through
fn.apply(this, args);
throttle = true;
} else { // all the others get throttled
if(timer) clearTimeout(timer); // cancel #2
timer = setTimeout(() => {
fn.apply(this, args);
timer = throttle = false;
}, ms);
}
};
}
// Attach click handler to the DT
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
for (const annoteDlNode of annoteDls) {
annoteDlNode.addEventListener('click', (event) => {
const clickedEl = event.target;
if (clickedEl !== selectedAnnoteEl) {
unselectCodeLines();
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
if (activeEl) {
activeEl.classList.remove('code-annotation-active');
}
selectCodeLines(clickedEl);
clickedEl.classList.add('code-annotation-active');
} else {
// Unselect the line
unselectCodeLines();
clickedEl.classList.remove('code-annotation-active');
}
});
}
const findCites = (el) => {
const parentEl = el.parentElement;
if (parentEl) {
const cites = parentEl.dataset.cites;
if (cites) {
return {
el,
cites: cites.split(' ')
};
} else {
return findCites(el.parentElement)
}
} else {
return undefined;
}
};
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
for (var i=0; i<bibliorefs.length; i++) {
const ref = bibliorefs[i];
const citeInfo = findCites(ref);
if (citeInfo) {
tippyHover(citeInfo.el, function() {
var popup = window.document.createElement('div');
citeInfo.cites.forEach(function(cite) {
var citeDiv = window.document.createElement('div');
citeDiv.classList.add('hanging-indent');
citeDiv.classList.add('csl-entry');
var biblioDiv = window.document.getElementById('ref-' + cite);
if (biblioDiv) {
citeDiv.innerHTML = biblioDiv.innerHTML;
}
popup.appendChild(citeDiv);
});
return popup.innerHTML;
});
}
}
});
</script>
</div> <!-- /content -->
</body></html>

5
.trash/Bienvenue.md Normal file
View file

@ -0,0 +1,5 @@
lVoici votre nouveau *coffre*.
Notez quelque chose, [[créez un lien]], ou essayez [l'importateur](https://help.obsidian.md/Plugins/Importer)!
Lorsque vous serez prêt, supprimez cette note et faites ce coffre vôtre.

9
.trash/anchor.min 2.js Normal file

File diff suppressed because one or more lines are too long

9
.trash/anchor.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2078
.trash/bootstrap-icons 2.css vendored Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

2078
.trash/bootstrap-icons.css vendored Normal file

File diff suppressed because it is too large Load diff

BIN
.trash/bootstrap-icons.woff Normal file

Binary file not shown.

7
.trash/bootstrap.min 2.js vendored Normal file

File diff suppressed because one or more lines are too long

7
.trash/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
.trash/clipboard.min.js vendored Normal file

File diff suppressed because one or more lines are too long

6
.trash/popper.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,205 @@
/* quarto syntax highlight colors */
:root {
--quarto-hl-ot-color: #003B4F;
--quarto-hl-at-color: #657422;
--quarto-hl-ss-color: #20794D;
--quarto-hl-an-color: #5E5E5E;
--quarto-hl-fu-color: #4758AB;
--quarto-hl-st-color: #20794D;
--quarto-hl-cf-color: #003B4F;
--quarto-hl-op-color: #5E5E5E;
--quarto-hl-er-color: #AD0000;
--quarto-hl-bn-color: #AD0000;
--quarto-hl-al-color: #AD0000;
--quarto-hl-va-color: #111111;
--quarto-hl-bu-color: inherit;
--quarto-hl-ex-color: inherit;
--quarto-hl-pp-color: #AD0000;
--quarto-hl-in-color: #5E5E5E;
--quarto-hl-vs-color: #20794D;
--quarto-hl-wa-color: #5E5E5E;
--quarto-hl-do-color: #5E5E5E;
--quarto-hl-im-color: #00769E;
--quarto-hl-ch-color: #20794D;
--quarto-hl-dt-color: #AD0000;
--quarto-hl-fl-color: #AD0000;
--quarto-hl-co-color: #5E5E5E;
--quarto-hl-cv-color: #5E5E5E;
--quarto-hl-cn-color: #8f5902;
--quarto-hl-sc-color: #5E5E5E;
--quarto-hl-dv-color: #AD0000;
--quarto-hl-kw-color: #003B4F;
}
/* other quarto variables */
:root {
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
pre > code.sourceCode > span {
color: #003B4F;
}
code span {
color: #003B4F;
}
code.sourceCode > span {
color: #003B4F;
}
div.sourceCode,
div.sourceCode pre.sourceCode {
color: #003B4F;
}
code span.ot {
color: #003B4F;
font-style: inherit;
}
code span.at {
color: #657422;
font-style: inherit;
}
code span.ss {
color: #20794D;
font-style: inherit;
}
code span.an {
color: #5E5E5E;
font-style: inherit;
}
code span.fu {
color: #4758AB;
font-style: inherit;
}
code span.st {
color: #20794D;
font-style: inherit;
}
code span.cf {
color: #003B4F;
font-weight: bold;
font-style: inherit;
}
code span.op {
color: #5E5E5E;
font-style: inherit;
}
code span.er {
color: #AD0000;
font-style: inherit;
}
code span.bn {
color: #AD0000;
font-style: inherit;
}
code span.al {
color: #AD0000;
font-style: inherit;
}
code span.va {
color: #111111;
font-style: inherit;
}
code span.bu {
font-style: inherit;
}
code span.ex {
font-style: inherit;
}
code span.pp {
color: #AD0000;
font-style: inherit;
}
code span.in {
color: #5E5E5E;
font-style: inherit;
}
code span.vs {
color: #20794D;
font-style: inherit;
}
code span.wa {
color: #5E5E5E;
font-style: italic;
}
code span.do {
color: #5E5E5E;
font-style: italic;
}
code span.im {
color: #00769E;
font-style: inherit;
}
code span.ch {
color: #20794D;
font-style: inherit;
}
code span.dt {
color: #AD0000;
font-style: inherit;
}
code span.fl {
color: #AD0000;
font-style: inherit;
}
code span.co {
color: #5E5E5E;
font-style: inherit;
}
code span.cv {
color: #5E5E5E;
font-style: italic;
}
code span.cn {
color: #8f5902;
font-style: inherit;
}
code span.sc {
color: #5E5E5E;
font-style: inherit;
}
code span.dv {
color: #AD0000;
font-style: inherit;
}
code span.kw {
color: #003B4F;
font-weight: bold;
font-style: inherit;
}
.prevent-inlining {
content: "</";
}
/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */

View file

@ -0,0 +1,205 @@
/* quarto syntax highlight colors */
:root {
--quarto-hl-ot-color: #003B4F;
--quarto-hl-at-color: #657422;
--quarto-hl-ss-color: #20794D;
--quarto-hl-an-color: #5E5E5E;
--quarto-hl-fu-color: #4758AB;
--quarto-hl-st-color: #20794D;
--quarto-hl-cf-color: #003B4F;
--quarto-hl-op-color: #5E5E5E;
--quarto-hl-er-color: #AD0000;
--quarto-hl-bn-color: #AD0000;
--quarto-hl-al-color: #AD0000;
--quarto-hl-va-color: #111111;
--quarto-hl-bu-color: inherit;
--quarto-hl-ex-color: inherit;
--quarto-hl-pp-color: #AD0000;
--quarto-hl-in-color: #5E5E5E;
--quarto-hl-vs-color: #20794D;
--quarto-hl-wa-color: #5E5E5E;
--quarto-hl-do-color: #5E5E5E;
--quarto-hl-im-color: #00769E;
--quarto-hl-ch-color: #20794D;
--quarto-hl-dt-color: #AD0000;
--quarto-hl-fl-color: #AD0000;
--quarto-hl-co-color: #5E5E5E;
--quarto-hl-cv-color: #5E5E5E;
--quarto-hl-cn-color: #8f5902;
--quarto-hl-sc-color: #5E5E5E;
--quarto-hl-dv-color: #AD0000;
--quarto-hl-kw-color: #003B4F;
}
/* other quarto variables */
:root {
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
pre > code.sourceCode > span {
color: #003B4F;
}
code span {
color: #003B4F;
}
code.sourceCode > span {
color: #003B4F;
}
div.sourceCode,
div.sourceCode pre.sourceCode {
color: #003B4F;
}
code span.ot {
color: #003B4F;
font-style: inherit;
}
code span.at {
color: #657422;
font-style: inherit;
}
code span.ss {
color: #20794D;
font-style: inherit;
}
code span.an {
color: #5E5E5E;
font-style: inherit;
}
code span.fu {
color: #4758AB;
font-style: inherit;
}
code span.st {
color: #20794D;
font-style: inherit;
}
code span.cf {
color: #003B4F;
font-weight: bold;
font-style: inherit;
}
code span.op {
color: #5E5E5E;
font-style: inherit;
}
code span.er {
color: #AD0000;
font-style: inherit;
}
code span.bn {
color: #AD0000;
font-style: inherit;
}
code span.al {
color: #AD0000;
font-style: inherit;
}
code span.va {
color: #111111;
font-style: inherit;
}
code span.bu {
font-style: inherit;
}
code span.ex {
font-style: inherit;
}
code span.pp {
color: #AD0000;
font-style: inherit;
}
code span.in {
color: #5E5E5E;
font-style: inherit;
}
code span.vs {
color: #20794D;
font-style: inherit;
}
code span.wa {
color: #5E5E5E;
font-style: italic;
}
code span.do {
color: #5E5E5E;
font-style: italic;
}
code span.im {
color: #00769E;
font-style: inherit;
}
code span.ch {
color: #20794D;
font-style: inherit;
}
code span.dt {
color: #AD0000;
font-style: inherit;
}
code span.fl {
color: #AD0000;
font-style: inherit;
}
code span.co {
color: #5E5E5E;
font-style: inherit;
}
code span.cv {
color: #5E5E5E;
font-style: italic;
}
code span.cn {
color: #8f5902;
font-style: inherit;
}
code span.sc {
color: #5E5E5E;
font-style: inherit;
}
code span.dv {
color: #AD0000;
font-style: inherit;
}
code span.kw {
color: #003B4F;
font-weight: bold;
font-style: inherit;
}
.prevent-inlining {
content: "</";
}
/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */

908
.trash/quarto.js Normal file
View file

@ -0,0 +1,908 @@
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
detail: {},
bubbles: true,
cancelable: false,
composed: false,
});
const layoutMarginEls = () => {
// Find any conflicting margin elements and add margins to the
// top to prevent overlap
const marginChildren = window.document.querySelectorAll(
".column-margin.column-container > *, .margin-caption, .aside"
);
let lastBottom = 0;
for (const marginChild of marginChildren) {
if (marginChild.offsetParent !== null) {
// clear the top margin so we recompute it
marginChild.style.marginTop = null;
const top = marginChild.getBoundingClientRect().top + window.scrollY;
if (top < lastBottom) {
const marginChildStyle = window.getComputedStyle(marginChild);
const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
const margin = lastBottom - top + marginBottom;
marginChild.style.marginTop = `${margin}px`;
}
const styles = window.getComputedStyle(marginChild);
const marginTop = parseFloat(styles["marginTop"]);
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
}
}
};
window.document.addEventListener("DOMContentLoaded", function (_event) {
// Recompute the position of margin elements anytime the body size changes
if (window.ResizeObserver) {
const resizeObserver = new window.ResizeObserver(
throttle(() => {
layoutMarginEls();
if (
window.document.body.getBoundingClientRect().width < 990 &&
isReaderMode()
) {
quartoToggleReader();
}
}, 50)
);
resizeObserver.observe(window.document.body);
}
const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
const sidebarEl = window.document.getElementById("quarto-sidebar");
const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
const marginSidebarEl = window.document.getElementById(
"quarto-margin-sidebar"
);
// function to determine whether the element has a previous sibling that is active
const prevSiblingIsActiveLink = (el) => {
const sibling = el.previousElementSibling;
if (sibling && sibling.tagName === "A") {
return sibling.classList.contains("active");
} else {
return false;
}
};
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
function fireSlideEnter(e) {
const event = window.document.createEvent("Event");
event.initEvent("slideenter", true, true);
window.document.dispatchEvent(event);
}
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
tabs.forEach((tab) => {
tab.addEventListener("shown.bs.tab", fireSlideEnter);
});
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
document.addEventListener("tabby", fireSlideEnter, false);
// Track scrolling and mark TOC links as active
// get table of contents and sidebar (bail if we don't have at least one)
const tocLinks = tocEl
? [...tocEl.querySelectorAll("a[data-scroll-target]")]
: [];
const makeActive = (link) => tocLinks[link].classList.add("active");
const removeActive = (link) => tocLinks[link].classList.remove("active");
const removeAllActive = () =>
[...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
// activate the anchor for a section associated with this TOC entry
tocLinks.forEach((link) => {
link.addEventListener("click", () => {
if (link.href.indexOf("#") !== -1) {
const anchor = link.href.split("#")[1];
const heading = window.document.querySelector(
`[data-anchor-id="${anchor}"]`
);
if (heading) {
// Add the class
heading.classList.add("reveal-anchorjs-link");
// function to show the anchor
const handleMouseout = () => {
heading.classList.remove("reveal-anchorjs-link");
heading.removeEventListener("mouseout", handleMouseout);
};
// add a function to clear the anchor when the user mouses out of it
heading.addEventListener("mouseout", handleMouseout);
}
}
});
});
const sections = tocLinks.map((link) => {
const target = link.getAttribute("data-scroll-target");
if (target.startsWith("#")) {
return window.document.getElementById(decodeURI(`${target.slice(1)}`));
} else {
return window.document.querySelector(decodeURI(`${target}`));
}
});
const sectionMargin = 200;
let currentActive = 0;
// track whether we've initialized state the first time
let init = false;
const updateActiveLink = () => {
// The index from bottom to top (e.g. reversed list)
let sectionIndex = -1;
if (
window.innerHeight + window.pageYOffset >=
window.document.body.offsetHeight
) {
// This is the no-scroll case where last section should be the active one
sectionIndex = 0;
} else {
// This finds the last section visible on screen that should be made active
sectionIndex = [...sections].reverse().findIndex((section) => {
if (section) {
return window.pageYOffset >= section.offsetTop - sectionMargin;
} else {
return false;
}
});
}
if (sectionIndex > -1) {
const current = sections.length - sectionIndex - 1;
if (current !== currentActive) {
removeAllActive();
currentActive = current;
makeActive(current);
if (init) {
window.dispatchEvent(sectionChanged);
}
init = true;
}
}
};
const inHiddenRegion = (top, bottom, hiddenRegions) => {
for (const region of hiddenRegions) {
if (top <= region.bottom && bottom >= region.top) {
return true;
}
}
return false;
};
const categorySelector = "header.quarto-title-block .quarto-category";
const activateCategories = (href) => {
// Find any categories
// Surround them with a link pointing back to:
// #category=Authoring
try {
const categoryEls = window.document.querySelectorAll(categorySelector);
for (const categoryEl of categoryEls) {
const categoryText = categoryEl.textContent;
if (categoryText) {
const link = `${href}#category=${encodeURIComponent(categoryText)}`;
const linkEl = window.document.createElement("a");
linkEl.setAttribute("href", link);
for (const child of categoryEl.childNodes) {
linkEl.append(child);
}
categoryEl.appendChild(linkEl);
}
}
} catch {
// Ignore errors
}
};
function hasTitleCategories() {
return window.document.querySelector(categorySelector) !== null;
}
function offsetRelativeUrl(url) {
const offset = getMeta("quarto:offset");
return offset ? offset + url : url;
}
function offsetAbsoluteUrl(url) {
const offset = getMeta("quarto:offset");
const baseUrl = new URL(offset, window.location);
const projRelativeUrl = url.replace(baseUrl, "");
if (projRelativeUrl.startsWith("/")) {
return projRelativeUrl;
} else {
return "/" + projRelativeUrl;
}
}
// read a meta tag value
function getMeta(metaName) {
const metas = window.document.getElementsByTagName("meta");
for (let i = 0; i < metas.length; i++) {
if (metas[i].getAttribute("name") === metaName) {
return metas[i].getAttribute("content");
}
}
return "";
}
async function findAndActivateCategories() {
const currentPagePath = offsetAbsoluteUrl(window.location.href);
const response = await fetch(offsetRelativeUrl("listings.json"));
if (response.status == 200) {
return response.json().then(function (listingPaths) {
const listingHrefs = [];
for (const listingPath of listingPaths) {
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
for (const item of listingPath.items) {
if (
item === currentPagePath ||
item === currentPagePath + "index.html"
) {
// Resolve this path against the offset to be sure
// we already are using the correct path to the listing
// (this adjusts the listing urls to be rooted against
// whatever root the page is actually running against)
const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
const baseUrl = window.location;
const resolvedPath = new URL(relative, baseUrl);
listingHrefs.push(resolvedPath.pathname);
break;
}
}
}
// Look up the tree for a nearby linting and use that if we find one
const nearestListing = findNearestParentListing(
offsetAbsoluteUrl(window.location.pathname),
listingHrefs
);
if (nearestListing) {
activateCategories(nearestListing);
} else {
// See if the referrer is a listing page for this item
const referredRelativePath = offsetAbsoluteUrl(document.referrer);
const referrerListing = listingHrefs.find((listingHref) => {
const isListingReferrer =
listingHref === referredRelativePath ||
listingHref === referredRelativePath + "index.html";
return isListingReferrer;
});
if (referrerListing) {
// Try to use the referrer if possible
activateCategories(referrerListing);
} else if (listingHrefs.length > 0) {
// Otherwise, just fall back to the first listing
activateCategories(listingHrefs[0]);
}
}
});
}
}
if (hasTitleCategories()) {
findAndActivateCategories();
}
const findNearestParentListing = (href, listingHrefs) => {
if (!href || !listingHrefs) {
return undefined;
}
// Look up the tree for a nearby linting and use that if we find one
const relativeParts = href.substring(1).split("/");
while (relativeParts.length > 0) {
const path = relativeParts.join("/");
for (const listingHref of listingHrefs) {
if (listingHref.startsWith(path)) {
return listingHref;
}
}
relativeParts.pop();
}
return undefined;
};
const manageSidebarVisiblity = (el, placeholderDescriptor) => {
let isVisible = true;
let elRect;
return (hiddenRegions) => {
if (el === null) {
return;
}
// Find the last element of the TOC
const lastChildEl = el.lastElementChild;
if (lastChildEl) {
// Converts the sidebar to a menu
const convertToMenu = () => {
for (const child of el.children) {
child.style.opacity = 0;
child.style.overflow = "hidden";
child.style.pointerEvents = "none";
}
nexttick(() => {
const toggleContainer = window.document.createElement("div");
toggleContainer.style.width = "100%";
toggleContainer.classList.add("zindex-over-content");
toggleContainer.classList.add("quarto-sidebar-toggle");
toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
toggleContainer.id = placeholderDescriptor.id;
toggleContainer.style.position = "fixed";
const toggleIcon = window.document.createElement("i");
toggleIcon.classList.add("quarto-sidebar-toggle-icon");
toggleIcon.classList.add("bi");
toggleIcon.classList.add("bi-caret-down-fill");
const toggleTitle = window.document.createElement("div");
const titleEl = window.document.body.querySelector(
placeholderDescriptor.titleSelector
);
if (titleEl) {
toggleTitle.append(
titleEl.textContent || titleEl.innerText,
toggleIcon
);
}
toggleTitle.classList.add("zindex-over-content");
toggleTitle.classList.add("quarto-sidebar-toggle-title");
toggleContainer.append(toggleTitle);
const toggleContents = window.document.createElement("div");
toggleContents.classList = el.classList;
toggleContents.classList.add("zindex-over-content");
toggleContents.classList.add("quarto-sidebar-toggle-contents");
for (const child of el.children) {
if (child.id === "toc-title") {
continue;
}
const clone = child.cloneNode(true);
clone.style.opacity = 1;
clone.style.pointerEvents = null;
clone.style.display = null;
toggleContents.append(clone);
}
toggleContents.style.height = "0px";
const positionToggle = () => {
// position the element (top left of parent, same width as parent)
if (!elRect) {
elRect = el.getBoundingClientRect();
}
toggleContainer.style.left = `${elRect.left}px`;
toggleContainer.style.top = `${elRect.top}px`;
toggleContainer.style.width = `${elRect.width}px`;
};
positionToggle();
toggleContainer.append(toggleContents);
el.parentElement.prepend(toggleContainer);
// Process clicks
let tocShowing = false;
// Allow the caller to control whether this is dismissed
// when it is clicked (e.g. sidebar navigation supports
// opening and closing the nav tree, so don't dismiss on click)
const clickEl = placeholderDescriptor.dismissOnClick
? toggleContainer
: toggleTitle;
const closeToggle = () => {
if (tocShowing) {
toggleContainer.classList.remove("expanded");
toggleContents.style.height = "0px";
tocShowing = false;
}
};
// Get rid of any expanded toggle if the user scrolls
window.document.addEventListener(
"scroll",
throttle(() => {
closeToggle();
}, 50)
);
// Handle positioning of the toggle
window.addEventListener(
"resize",
throttle(() => {
elRect = undefined;
positionToggle();
}, 50)
);
window.addEventListener("quarto-hrChanged", () => {
elRect = undefined;
});
// Process the click
clickEl.onclick = () => {
if (!tocShowing) {
toggleContainer.classList.add("expanded");
toggleContents.style.height = null;
tocShowing = true;
} else {
closeToggle();
}
};
});
};
// Converts a sidebar from a menu back to a sidebar
const convertToSidebar = () => {
for (const child of el.children) {
child.style.opacity = 1;
child.style.overflow = null;
child.style.pointerEvents = null;
}
const placeholderEl = window.document.getElementById(
placeholderDescriptor.id
);
if (placeholderEl) {
placeholderEl.remove();
}
el.classList.remove("rollup");
};
if (isReaderMode()) {
convertToMenu();
isVisible = false;
} else {
// Find the top and bottom o the element that is being managed
const elTop = el.offsetTop;
const elBottom =
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
if (!isVisible) {
// If the element is current not visible reveal if there are
// no conflicts with overlay regions
if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
convertToSidebar();
isVisible = true;
}
} else {
// If the element is visible, hide it if it conflicts with overlay regions
// and insert a placeholder toggle (or if we're in reader mode)
if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
convertToMenu();
isVisible = false;
}
}
}
}
};
};
const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
for (const tabEl of tabEls) {
const id = tabEl.getAttribute("data-bs-target");
if (id) {
const columnEl = document.querySelector(
`${id} .column-margin, .tabset-margin-content`
);
if (columnEl)
tabEl.addEventListener("shown.bs.tab", function (event) {
const el = event.srcElement;
if (el) {
const visibleCls = `${el.id}-margin-content`;
// walk up until we find a parent tabset
let panelTabsetEl = el.parentElement;
while (panelTabsetEl) {
if (panelTabsetEl.classList.contains("panel-tabset")) {
break;
}
panelTabsetEl = panelTabsetEl.parentElement;
}
if (panelTabsetEl) {
const prevSib = panelTabsetEl.previousElementSibling;
if (
prevSib &&
prevSib.classList.contains("tabset-margin-container")
) {
const childNodes = prevSib.querySelectorAll(
".tabset-margin-content"
);
for (const childEl of childNodes) {
if (childEl.classList.contains(visibleCls)) {
childEl.classList.remove("collapse");
} else {
childEl.classList.add("collapse");
}
}
}
}
}
layoutMarginEls();
});
}
}
// Manage the visibility of the toc and the sidebar
const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
id: "quarto-toc-toggle",
titleSelector: "#toc-title",
dismissOnClick: true,
});
const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
id: "quarto-sidebarnav-toggle",
titleSelector: ".title",
dismissOnClick: false,
});
let tocLeftScrollVisibility;
if (leftTocEl) {
tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
id: "quarto-lefttoc-toggle",
titleSelector: "#toc-title",
dismissOnClick: true,
});
}
// Find the first element that uses formatting in special columns
const conflictingEls = window.document.body.querySelectorAll(
'[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
);
// Filter all the possibly conflicting elements into ones
// the do conflict on the left or ride side
const arrConflictingEls = Array.from(conflictingEls);
const leftSideConflictEls = arrConflictingEls.filter((el) => {
if (el.tagName === "ASIDE") {
return false;
}
return Array.from(el.classList).find((className) => {
return (
className !== "column-body" &&
className.startsWith("column-") &&
!className.endsWith("right") &&
!className.endsWith("container") &&
className !== "column-margin"
);
});
});
const rightSideConflictEls = arrConflictingEls.filter((el) => {
if (el.tagName === "ASIDE") {
return true;
}
const hasMarginCaption = Array.from(el.classList).find((className) => {
return className == "margin-caption";
});
if (hasMarginCaption) {
return true;
}
return Array.from(el.classList).find((className) => {
return (
className !== "column-body" &&
!className.endsWith("container") &&
className.startsWith("column-") &&
!className.endsWith("left")
);
});
});
const kOverlapPaddingSize = 10;
function toRegions(els) {
return els.map((el) => {
const boundRect = el.getBoundingClientRect();
const top =
boundRect.top +
document.documentElement.scrollTop -
kOverlapPaddingSize;
return {
top,
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
};
});
}
let hasObserved = false;
const visibleItemObserver = (els) => {
let visibleElements = [...els];
const intersectionObserver = new IntersectionObserver(
(entries, _observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (visibleElements.indexOf(entry.target) === -1) {
visibleElements.push(entry.target);
}
} else {
visibleElements = visibleElements.filter((visibleEntry) => {
return visibleEntry !== entry;
});
}
});
if (!hasObserved) {
hideOverlappedSidebars();
}
hasObserved = true;
},
{}
);
els.forEach((el) => {
intersectionObserver.observe(el);
});
return {
getVisibleEntries: () => {
return visibleElements;
},
};
};
const rightElementObserver = visibleItemObserver(rightSideConflictEls);
const leftElementObserver = visibleItemObserver(leftSideConflictEls);
const hideOverlappedSidebars = () => {
marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
if (tocLeftScrollVisibility) {
tocLeftScrollVisibility(
toRegions(leftElementObserver.getVisibleEntries())
);
}
};
window.quartoToggleReader = () => {
// Applies a slow class (or removes it)
// to update the transition speed
const slowTransition = (slow) => {
const manageTransition = (id, slow) => {
const el = document.getElementById(id);
if (el) {
if (slow) {
el.classList.add("slow");
} else {
el.classList.remove("slow");
}
}
};
manageTransition("TOC", slow);
manageTransition("quarto-sidebar", slow);
};
const readerMode = !isReaderMode();
setReaderModeValue(readerMode);
// If we're entering reader mode, slow the transition
if (readerMode) {
slowTransition(readerMode);
}
highlightReaderToggle(readerMode);
hideOverlappedSidebars();
// If we're exiting reader mode, restore the non-slow transition
if (!readerMode) {
slowTransition(!readerMode);
}
};
const highlightReaderToggle = (readerMode) => {
const els = document.querySelectorAll(".quarto-reader-toggle");
if (els) {
els.forEach((el) => {
if (readerMode) {
el.classList.add("reader");
} else {
el.classList.remove("reader");
}
});
}
};
const setReaderModeValue = (val) => {
if (window.location.protocol !== "file:") {
window.localStorage.setItem("quarto-reader-mode", val);
} else {
localReaderMode = val;
}
};
const isReaderMode = () => {
if (window.location.protocol !== "file:") {
return window.localStorage.getItem("quarto-reader-mode") === "true";
} else {
return localReaderMode;
}
};
let localReaderMode = null;
const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
// Walk the TOC and collapse/expand nodes
// Nodes are expanded if:
// - they are top level
// - they have children that are 'active' links
// - they are directly below an link that is 'active'
const walk = (el, depth) => {
// Tick depth when we enter a UL
if (el.tagName === "UL") {
depth = depth + 1;
}
// It this is active link
let isActiveNode = false;
if (el.tagName === "A" && el.classList.contains("active")) {
isActiveNode = true;
}
// See if there is an active child to this element
let hasActiveChild = false;
for (child of el.children) {
hasActiveChild = walk(child, depth) || hasActiveChild;
}
// Process the collapse state if this is an UL
if (el.tagName === "UL") {
if (tocOpenDepth === -1 && depth > 1) {
// toc-expand: false
el.classList.add("collapse");
} else if (
depth <= tocOpenDepth ||
hasActiveChild ||
prevSiblingIsActiveLink(el)
) {
el.classList.remove("collapse");
} else {
el.classList.add("collapse");
}
// untick depth when we leave a UL
depth = depth - 1;
}
return hasActiveChild || isActiveNode;
};
// walk the TOC and expand / collapse any items that should be shown
if (tocEl) {
updateActiveLink();
walk(tocEl, 0);
}
// Throttle the scroll event and walk peridiocally
window.document.addEventListener(
"scroll",
throttle(() => {
if (tocEl) {
updateActiveLink();
walk(tocEl, 0);
}
if (!isReaderMode()) {
hideOverlappedSidebars();
}
}, 5)
);
window.addEventListener(
"resize",
throttle(() => {
if (tocEl) {
updateActiveLink();
walk(tocEl, 0);
}
if (!isReaderMode()) {
hideOverlappedSidebars();
}
}, 10)
);
hideOverlappedSidebars();
highlightReaderToggle(isReaderMode());
});
// grouped tabsets
window.addEventListener("pageshow", (_event) => {
function getTabSettings() {
const data = localStorage.getItem("quarto-persistent-tabsets-data");
if (!data) {
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
return {};
}
if (data) {
return JSON.parse(data);
}
}
function setTabSettings(data) {
localStorage.setItem(
"quarto-persistent-tabsets-data",
JSON.stringify(data)
);
}
function setTabState(groupName, groupValue) {
const data = getTabSettings();
data[groupName] = groupValue;
setTabSettings(data);
}
function toggleTab(tab, active) {
const tabPanelId = tab.getAttribute("aria-controls");
const tabPanel = document.getElementById(tabPanelId);
if (active) {
tab.classList.add("active");
tabPanel.classList.add("active");
} else {
tab.classList.remove("active");
tabPanel.classList.remove("active");
}
}
function toggleAll(selectedGroup, selectorsToSync) {
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
const active = selectedGroup === thisGroup;
for (const tab of tabs) {
toggleTab(tab, active);
}
}
}
function findSelectorsToSyncByLanguage() {
const result = {};
const tabs = Array.from(
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
);
for (const item of tabs) {
const div = item.parentElement.parentElement.parentElement;
const group = div.getAttribute("data-group");
if (!result[group]) {
result[group] = {};
}
const selectorsToSync = result[group];
const value = item.innerHTML;
if (!selectorsToSync[value]) {
selectorsToSync[value] = [];
}
selectorsToSync[value].push(item);
}
return result;
}
function setupSelectorSync() {
const selectorsToSync = findSelectorsToSyncByLanguage();
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
Object.entries(tabSetsByValue).forEach(([value, items]) => {
items.forEach((item) => {
item.addEventListener("click", (_event) => {
setTabState(group, value);
toggleAll(value, selectorsToSync[group]);
});
});
});
});
return selectorsToSync;
}
const selectorsToSync = setupSelectorSync();
for (const [group, selectedName] of Object.entries(getTabSettings())) {
const selectors = selectorsToSync[group];
// it's possible that stale state gives us empty selections, so we explicitly check here.
if (selectors) {
toggleAll(selectedName, selectors);
}
}
});
function throttle(func, wait) {
let waiting = false;
return function () {
if (!waiting) {
func.apply(this, arguments);
waiting = true;
setTimeout(function () {
waiting = false;
}, wait);
}
};
}
function nexttick(func) {
return setTimeout(func, 0);
}

1
.trash/tippy 2.css Normal file
View file

@ -0,0 +1 @@
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}

1
.trash/tippy.css Normal file
View file

@ -0,0 +1 @@
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}

2
.trash/tippy.umd.min.js vendored Normal file

File diff suppressed because one or more lines are too long

5
Bienvenue.md Normal file
View file

@ -0,0 +1,5 @@
Voici votre nouveau *coffre*.
Notez quelque chose, [[créez un lien]], ou essayez [l'importateur](https://help.obsidian.md/Plugins/Importer)!
Lorsque vous serez prêt, supprimez cette note et faites ce coffre vôtre.

Some files were not shown because too many files have changed in this diff Show more