jekyll-obsidian 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,175 @@
1
+ <!-- -------------------------------- Note --------------------------------- -->
2
+
3
+ <body>
4
+ <h3 id="note-title"></h3>
5
+ <div id="note-content"></div>
6
+ <ul id="linked-mentions"></ul>
7
+ </body>
8
+
9
+ <script>
10
+ function updateNotePadding(widthPercentage) {
11
+ if (window.innerWidth < 481) {
12
+ NOTE.style.paddingLeft = `${minPadding}vw`;
13
+ NOTE.style.paddingRight = `${minPadding}vw`;
14
+ } else {
15
+ let padding = linearMapInRange(widthPercentage,
16
+ minWidth,
17
+ maxWidth,
18
+ maxPadding,
19
+ minPadding);
20
+ NOTE.style.paddingLeft = `${padding}vw`;
21
+ NOTE.style.paddingRight = `${padding}vw`;
22
+ }
23
+ }
24
+
25
+ function loadNote(filePath, header = "") {
26
+ console.log("filePath: " + filePath);
27
+ if (filePath.startsWith('/'))
28
+ filePath = filePath.substring(1);
29
+ generateBreadcrumbs(filePath);
30
+ fetchNoteContent(filePath, header);
31
+ FILEREAD.removeEventListener('wheel', adjustCanvasScaleOnScroll);
32
+ }
33
+
34
+ function fetchNoteContent(filePath, header = "") {
35
+ const fullFilePath = getFullFilePath('/' + filePath);
36
+ console.debug("fullNoteFilePath: " + fullFilePath)
37
+ fetch(fullFilePath).then(response => {
38
+ if (!response.ok)
39
+ throw new Error('Network response: ' + response.statusText);
40
+ return response.text();
41
+ }).then(content => {
42
+ NOTE.querySelector('#note-title').textContent =
43
+ extractFilenameFromPath(filePath);
44
+
45
+ const noteDiv = parseStringToMarkdown(content);
46
+
47
+ NOTE.querySelector('#note-content').innerHTML =
48
+ DOMPurify.sanitize(noteDiv.innerHTML);
49
+ noteDiv.remove();
50
+
51
+ FILEREAD.scrollTop = 0;
52
+ FILEREAD.scrollLeft = 0;
53
+ if (header) {
54
+ const headers = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
55
+ headers.forEach((heading) => {
56
+ if (heading.textContent === header) heading.scrollIntoView();
57
+ });
58
+ }
59
+
60
+ if (BACKLINKS) {
61
+ mapBacklinksToJson(BACKLINKS);
62
+ generateLinkedMentions(filePath, BACKLINKS);
63
+ }
64
+ }).catch(error => {
65
+ console.error('Error fetching file:', error);
66
+ });
67
+ }
68
+ </script>
69
+
70
+ <!-- ---------------------- Generate Linked Mentions ----------------------- -->
71
+ <script>
72
+ function generateLinkedMentions(filePath, backlinks_parsed) {
73
+ const VAULTPATH = '/' + '{{ site.obsidian_vault | escape }}' + '/';
74
+ const linkedMentionsId =
75
+ NOTE.querySelector('#linked-mentions');
76
+ while (linkedMentionsId.firstChild)
77
+ linkedMentionsId.removeChild(linkedMentionsId.firstChild);
78
+ let linked_mentions = [];
79
+ for (const parsedFilePath in backlinks_parsed) {
80
+ const entry = backlinks_parsed[parsedFilePath];
81
+ entry.backlink_paths.forEach(path => {
82
+ if (path === filePath && parsedFilePath.endsWith('.mdnote')) {
83
+ linked_mentions.push(parsedFilePath.replace("/:|", "'"));
84
+ }
85
+ });
86
+ }
87
+ if (linked_mentions.length !== 0) {
88
+ const h4 = document.createElement('h4');
89
+ h4.textContent = 'Linked mentions';
90
+ linkedMentionsId.appendChild(h4);
91
+ }
92
+ linked_mentions.forEach(linkedMentionPath => {
93
+ const li = document.createElement('li');
94
+ const linkedPathName = extractFilenameFromPath(linkedMentionPath);
95
+ linkedMentionsId.appendChild(li);
96
+ li.classList.add('title');
97
+ const decodedString = he.decode(linkedPathName);
98
+ li.textContent = decodedString;
99
+
100
+ const linkedMentionPathFull = VAULTPATH + linkedMentionPath;
101
+ fetch(linkedMentionPathFull)
102
+ .then(response => {
103
+ if (!response.ok)
104
+ throw new Error('Network response: ' + response.statusText);
105
+ return response.text();
106
+ }).then(content => {
107
+ const ul_linkedMention = document.createElement('ul');
108
+ li.appendChild(ul_linkedMention);
109
+ const backlink = `[[${extractFilenameFromPath(filePath)}]]`;
110
+ let lines = content.split('\n');
111
+ lines.forEach(line => {
112
+ if (line) {
113
+ const line_backlinks = extractBacklinks(line);
114
+ if (line_backlinks) {
115
+ line_backlinks.forEach(line_backlink => {
116
+ const ulBtns =
117
+ Array.from(ul_linkedMention.querySelectorAll('button'));
118
+ const btnText = ulBtns.map(button => button.textContent);
119
+ const stripped_backlink =
120
+ line_backlink.toLowerCase()
121
+ .replace(/\|.*?\]\]/, ']]')
122
+ .replace(/#.*?\]\]/, ']]');
123
+ if (stripped_backlink === backlink.toLowerCase())
124
+ if (!btnText.includes(line)) {
125
+ const btn = document.createElement('button');
126
+ btn.textContent = line;
127
+ btn.classList.add('sentence');
128
+ btn.dataset.filePath = linkedMentionPathFull;
129
+
130
+ btn.addEventListener('click', function () {
131
+ const filePath =
132
+ this.dataset.filePath.replace(VAULTPATH, '');
133
+ dispatchFileSelectEvt(filePath);
134
+ });
135
+ ul_linkedMention.appendChild(btn);
136
+ }
137
+ });
138
+ }
139
+ }
140
+ });
141
+ })
142
+ .catch(error => {
143
+ console.error('Error fetching file:', error);
144
+ });
145
+ });
146
+ }
147
+ </script>
148
+
149
+ <!-- ------------------------ Note event listeners ------------------------- -->
150
+ <script>
151
+ document.addEventListener('DOMContentLoaded', () => {
152
+ var lastFileCookie = Cookies.get('last-file');
153
+ if (lastFileCookie) {
154
+ dispatchFileSelectEvt(lastFileCookie, null);
155
+ } else {
156
+ console.info('No last file found.');
157
+ let homepage = '{{ site.obsidian_homepage | escape }}';
158
+ if (homepage) {
159
+ if (homepage.endsWith('.md'))
160
+ homepage = homepage.replace('.md', '.mdnote');
161
+
162
+ if (homepage.endsWith('.mdnote')) {
163
+ switchPage(homepage);
164
+ loadNote(homepage);
165
+ console.log("note loaded: " + homepage);
166
+ }
167
+ }
168
+ }
169
+ });
170
+
171
+ document.addEventListener('obsidian_noteSelect', function (event) {
172
+ switchPage(event.detail.filePath);
173
+ loadNote(event.detail.filePath, event.detail.heading);
174
+ });
175
+ </script>
@@ -0,0 +1,106 @@
1
+ <body>
2
+ <div id="top-container">
3
+ <button id="homepage" onclick="loadHomepage()">
4
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
5
+ viewBox="0 0 24 24">
6
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
7
+ d="m4 12 8-8 8 8M6 10.5V19a1 1 0 0 0 1 1h3v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h3a1 1 0 0 0 1-1v-8.5" />
8
+ </svg>
9
+ </button>
10
+ <button id="search" onclick="dispatchModalSelectEvt('search')" popovertarget="search-modal">
11
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none"
12
+ viewBox="0 0 24 24">
13
+ <path stroke="currentColor" stroke-linecap="round" stroke-width="2"
14
+ d="m21 21-3.5-3.5M17 10a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z" />
15
+ </svg>
16
+
17
+ </button>
18
+ <button id="tags" onclick="dispatchModalSelectEvt('tags')">
19
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 16 16">
20
+ <path
21
+ d="M3 2v4.586l7 7L14.586 9l-7-7zM2 2a1 1 0 0 1 1-1h4.586a1 1 0 0 1 .707.293l7 7a1 1 0 0 1 0 1.414l-4.586 4.586a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 2 6.586z" />
22
+ <path
23
+ d="M5.5 5a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1m0 1a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M1 7.086a1 1 0 0 0 .293.707L8.75 15.25l-.043.043a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 0 7.586V3a1 1 0 0 1 1-1z" />
24
+ </svg>
25
+ </button>
26
+ </div>
27
+ <div id="bottom-container">
28
+ <button id="info" onclick="dispatchModalSelectEvt('info')" popovertarget="info-modal">
29
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
30
+ viewBox="0 0 24 24">
31
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
32
+ d="M10 11h2v5m-2 0h4m-2.592-8.5h.01M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
33
+ </svg>
34
+ </button>
35
+ </div>
36
+ </body>
37
+ <!-- ---------------------------- Load homepage ---------------------------- -->
38
+ <script>
39
+ function loadHomepage() {
40
+ let homepage = '{{ site.obsidian_homepage | escape }}';
41
+ if (homepage) {
42
+ if (homepage.endsWith('.md'))
43
+ homepage = homepage.replace('.md', '.mdnote');
44
+ if (homepage.endsWith('.mdnote')) {
45
+ switchPage(homepage);
46
+ loadNote(homepage);
47
+ }
48
+ }
49
+ }
50
+ </script>
51
+
52
+ <!-- ------------------------- Sidebar DOM events -------------------------- -->
53
+ <script>
54
+ document.addEventListener('DOMContentLoaded', () => {
55
+ const homepage = '{{ site.obsidian_homepage | escape }}'
56
+ const breadcrumbs = SIDEBAR.querySelector('button#homepage');
57
+
58
+ if (!homepage) { breadcrumbs.style.display = "none"; }
59
+ });
60
+ function dispatchModalSelectEvt(modalType, modalData = '') {
61
+ switch (modalType) {
62
+ case 'info':
63
+ default:
64
+ console.debug("selected info modal");
65
+ break;
66
+ case 'search':
67
+ console.debug("selected search modal");
68
+ break;
69
+ case 'tags':
70
+ console.debug("selected tags modal");
71
+ // const clonedNote = NOTE.cloneNode(true); // `true` ensures deep cloning (copy all child nodes)
72
+
73
+ // // Step 3: Modify the ID of the cloned element
74
+ // // Generate a unique ID, perhaps by using a timestamp or an incrementing index
75
+ // clonedNote.id = `note-${Date.now()}`;
76
+
77
+ // // Step 4: Append the cloned element to its new parent
78
+ // const notes = FILEREAD.querySelector('#notes');
79
+ // notes.appendChild(clonedNote);
80
+ break;
81
+ case 'media':
82
+ console.debug("selected media modal");
83
+ break;
84
+ }
85
+ const detail = { modalType, modalData };
86
+ const event = new CustomEvent('obsidian_modalSelect', { detail });
87
+ document.dispatchEvent(event);
88
+ }
89
+
90
+ const Modal = {
91
+ Info: "Info",
92
+ Search: "Search",
93
+ Media: "Media",
94
+ };
95
+ function toggleModals(modal) {
96
+ switch (modal) {
97
+ case Modal.Info:
98
+ default:
99
+ break;
100
+ case Modal.Search:
101
+ break;
102
+ case Modal.Media:
103
+ break;
104
+ }
105
+ }
106
+ </script>
@@ -0,0 +1,294 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ page.lang | default: site.lang | default: " en" }}">
3
+
4
+ <head>
5
+ <script src="https://cdn.jsdelivr.net/npm/he@latest/he.min.js"></script>
6
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.6/purify.min.js"></script>
7
+ <script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
8
+ <link rel="stylesheet" href="{{ '/assets/obsidian/obsidian.css' | relative_url }}">
9
+ <style>
10
+ .page-content {
11
+ display: flex;
12
+ height: 100%;
13
+ padding: 0 !important;
14
+ max-height: 100vh;
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ {%- include head.html -%}
20
+
21
+ <body>
22
+ {%- include header.html -%}
23
+
24
+ <main class="page-content" aria-label="Content">
25
+ <div id="loading-spinner"></div>
26
+ <div id="obsidian" style="display: none;">
27
+ <div id="sidebar">
28
+ {% include obsidian/sidebar.html -%}
29
+ {%- include obsidian/modals.html -%}
30
+ </div>
31
+ <div id="explorer">
32
+ {% include obsidian/explorer.html %}
33
+ </div>
34
+ <div id="divider"></div>
35
+ <div id="fileread">
36
+ <ul id="breadcrumb"> </ul>
37
+ {% include obsidian/fileread.html %}
38
+ <div id="notes">
39
+ <div id="note" style="display: flex;">
40
+ {% include obsidian/note.html %}
41
+ </div>
42
+ </div>
43
+ <div id="canvas" style="display: none;">
44
+ {% include obsidian/canvas.html %}
45
+ </div>
46
+ </div>
47
+ </main>
48
+ <!-- {%- include footer.html -%} -->
49
+ </body>
50
+
51
+ <!-- ----------------------- Constants initilization ----------------------- -->
52
+ <script>
53
+ // ! ELEMENT SELECTORS
54
+ const OBSIDIAN = document.getElementById('obsidian');
55
+
56
+ const SIDEBAR = OBSIDIAN.querySelector('#sidebar');
57
+
58
+ const DIVIDER = OBSIDIAN.querySelector("#divider");
59
+
60
+ const MODALS = OBSIDIAN.querySelector('#modals');
61
+ const mediaModal = MODALS.querySelector('#media-modal');
62
+ const media = mediaModal.querySelector("#media");
63
+ const mediaData = mediaModal.querySelector("#media-data");
64
+
65
+ const FILEREAD = OBSIDIAN.querySelector('#fileread');
66
+ const NOTE = FILEREAD.querySelector('#note');
67
+ const CANVAS = FILEREAD.querySelector('#canvas');
68
+
69
+ // ! GLOBAL CONSTS
70
+ const minWidth = 10; const maxWidth = 50;
71
+ const minPadding = 3.5; const maxPadding = 23;
72
+ </script>
73
+
74
+ <!-- -------------------------- Utility functions -------------------------- -->
75
+ <script>
76
+ // Linear mapping function
77
+ function linearMapInRange(value, x1, y1, x2, y2) {
78
+ return (value - x1) * (y2 - x2) / (y1 - x1) + x2;
79
+ }
80
+ </script>
81
+
82
+ <!-- ------------------------ Divider drag handler ------------------------- -->
83
+ <script>
84
+ let isDraggingDivider = false;
85
+ let startX, startWidth;
86
+
87
+ DIVIDER.addEventListener('mousedown', (e) => {
88
+ EXPLORER = OBSIDIAN.querySelector('#explorer');
89
+ isDraggingDivider = true;
90
+ startX = e.clientX;
91
+ startWidth = EXPLORER.getBoundingClientRect().width;
92
+ document.addEventListener('mousemove', onMouseMove);
93
+ document.addEventListener('mouseup', onMouseUp);
94
+ });
95
+
96
+ function onMouseMove(e) {
97
+ if (!isDraggingDivider) return;
98
+ let offset = e.clientX - startX;
99
+ let newWidthPx = startWidth + offset;
100
+ let newWidthPercent = newWidthPx / window.innerWidth * 100;
101
+ newWidthPercent = Math.max(minWidth, Math.min(newWidthPercent, maxWidth));
102
+ EXPLORER.style.width = `${newWidthPercent}%`;
103
+ updateNotePadding(newWidthPercent);
104
+ }
105
+
106
+ function onMouseUp() {
107
+ isDraggingDivider = false;
108
+ document.removeEventListener('mousemove', onMouseMove);
109
+ document.removeEventListener('mouseup', onMouseUp);
110
+ }
111
+ </script>
112
+
113
+ <!-- --------------------------- On content load --------------------------- -->
114
+ <script>
115
+ let EXPLORER = OBSIDIAN.querySelector('#explorer');
116
+ window.addEventListener('resize', function () { refreshScreenSize(); });
117
+
118
+ document.addEventListener('DOMContentLoaded', (event) => {
119
+ EXPLORER = OBSIDIAN.querySelector('#explorer');
120
+ refreshScreenSize();
121
+
122
+ OBSIDIAN.style.display = '';
123
+ var loadingDiv = document.getElementById('loading-spinner');
124
+ loadingDiv.style.display = 'none';
125
+ });
126
+
127
+ function refreshScreenSize() {
128
+ let explorerWidthPx = parseFloat(getComputedStyle(EXPLORER).width);
129
+ let parentWidthPx = parseFloat(getComputedStyle(EXPLORER.parentElement).width);
130
+ let explorerWidthPercent = (explorerWidthPx / parentWidthPx) * 100;
131
+ updateNotePadding(explorerWidthPercent);
132
+ if (window.innerWidth < 481) {
133
+ DIVIDER.style.display = 'none';
134
+ EXPLORER.style.display = 'none';
135
+ FILEREAD.style.display = '';
136
+ } else {
137
+ DIVIDER.style.display = '';
138
+ EXPLORER.style.display = '';
139
+ EXPLORER.style.width = '18%';
140
+ }
141
+ }
142
+ </script>
143
+
144
+ <!-- ------------------------------- Getters ------------------------------- -->
145
+ <script>
146
+ function getFullFilePath(filePath, trimTrailingPeriod = true) {
147
+ const VAULTPATH = '{{ site.obsidian_vault | escape }}';
148
+ if (trimTrailingPeriod)
149
+ return removeExtraTrailingDotFromFilename(fullFilePath = '/' + VAULTPATH + filePath);
150
+ else return fullFilePath = '/' + VAULTPATH + filePath;
151
+ }
152
+
153
+ function getFileType(filePath) {
154
+ const extensionToType = {
155
+ // Images
156
+ 'jpg': 'image', 'jpeg': 'image', 'png': 'image', 'gif': 'image', 'bmp': 'image', 'webp': 'image',
157
+ // PDFs
158
+ 'pdf': 'pdf',
159
+ // SVGs
160
+ 'svg': 'svg',
161
+ // Audios
162
+ 'mp3': 'audio', 'wav': 'audio', 'ogg': 'audio',
163
+ // Videos
164
+ 'mp4': 'video', 'avi': 'video', 'mov': 'video', 'mkv': 'video', 'webm': 'video',
165
+ };
166
+ // Extract the file extension
167
+ const extension = filePath.split('.').pop().toLowerCase();
168
+ console.log("extension: ", extension);
169
+ // Return the file type, defaulting to 'unknown' if the extension is not in the map
170
+ return extensionToType[extension] || 'unknown';
171
+ }
172
+
173
+ const Icon = {
174
+ // ------------------------------- sidebar -------------------------------
175
+ Homepage: "Homepage",
176
+ Search: "Search",
177
+ Tags: "Tags",
178
+ Settings: "Settings",
179
+ // ------------------------------ explorer -------------------------------
180
+ RightArrow: "RightArrow",
181
+ DownArrow: "DownArrow",
182
+ ChevronExpand: "ChevronExpand",
183
+ ChevronCollapse: "ChevronCollapse",
184
+ // ------------------------------ callouts -------------------------------
185
+ Note: "Note",
186
+ Info: "Info",
187
+ Tip: "Tip",
188
+ Todo: "Todo",
189
+ Question: "Question",
190
+ Success: "Success",
191
+ Failure: "Failure",
192
+ Warning: "Warning",
193
+ Example: "Example",
194
+
195
+ };
196
+
197
+ function getSVGIcon(icon) {
198
+ switch (icon) {
199
+ // ------------------------------- sidebar ------------------------------- -->
200
+ case Icon.Homepage:
201
+ return `
202
+ <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
203
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
204
+ d="m4 12 8-8 8 8M6 10.5V19a1 1 0 0 0 1 1h3v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h3a1 1 0 0 0 1-1v-8.5" />
205
+ </svg>`;
206
+ case Icon.Search:
207
+ return `
208
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
209
+ <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
210
+ </svg>`;
211
+ case Icon.Tags:
212
+ return `
213
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tags" viewBox="0 0 16 16">
214
+ <path d="M3 2v4.586l7 7L14.586 9l-7-7zM2 2a1 1 0 0 1 1-1h4.586a1 1 0 0 1 .707.293l7 7a1 1 0 0 1 0 1.414l-4.586 4.586a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 2 6.586z"/>
215
+ <path d="M5.5 5a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1m0 1a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M1 7.086a1 1 0 0 0 .293.707L8.75 15.25l-.043.043a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 0 7.586V3a1 1 0 0 1 1-1z"/>
216
+ </svg>`;
217
+ case Icon.Settings:
218
+ break;
219
+ // ------------------------------ explorer ------------------------------- -->
220
+ case Icon.RightArrow:
221
+ return `
222
+ <svg class="svg_RightArrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
223
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 5 7 7-7 7"/>
224
+ </svg>`;
225
+ case Icon.DownArrow:
226
+ return `
227
+ <svg class="svg_downArrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
228
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m5 9 7 7 7-7"/>
229
+ </svg>`;
230
+ case Icon.ChevronExpand:
231
+ return `
232
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-expand" viewBox="0 0 16 16">
233
+ <path fill-rule="evenodd" d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708m0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708"/>
234
+ </svg>`;
235
+ case Icon.ChevronCollapse:
236
+ return `
237
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-contract" viewBox="0 0 16 16">
238
+ <path fill-rule="evenodd" d="M3.646 13.854a.5.5 0 0 0 .708 0L8 10.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708m0-11.708a.5.5 0 0 1 .708 0L8 5.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708"/>
239
+ </svg>`;
240
+ // ------------------------------ callouts -------------------------------
241
+ case Icon.Note:
242
+ return `
243
+ <svg class="svg_Note" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
244
+ <polygon points="16 3 21 8 8 21 3 21 3 16 16 3"></polygon>
245
+ </svg>`;
246
+ case Icon.Info:
247
+ return `
248
+ <svg class="svg_Info" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
249
+ viewBox="0 0 24 24">
250
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
251
+ d="M10 11h2v5m-2 0h4m-2.592-8.5h.01M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
252
+ </svg>`;
253
+ case Icon.Tip:
254
+ return `
255
+ <svg class="svg_Tip" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
256
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.122 17.645a7.185 7.185 0 0 1-2.656 2.495 7.06 7.06 0 0 1-3.52.853 6.617 6.617 0 0 1-3.306-.718 6.73 6.73 0 0 1-2.54-2.266c-2.672-4.57.287-8.846.887-9.668A4.448 4.448 0 0 0 8.07 6.31 4.49 4.49 0 0 0 7.997 4c1.284.965 6.43 3.258 5.525 10.631 1.496-1.136 2.7-3.046 2.846-6.216 1.43 1.061 3.985 5.462 1.754 9.23Z" />
257
+ </svg>`;
258
+ case Icon.Todo:
259
+ return `
260
+ <svg class="svg_Todo" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
261
+ <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline>
262
+ </svg>`;
263
+ case Icon.Question:
264
+ return `
265
+ <svg class="svg_Question" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
266
+ <circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line>
267
+ </svg>`;
268
+ case Icon.Success:
269
+ return `
270
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
271
+ <polyline points="20 6 9 17 4 12"></polyline>
272
+ </svg>`;
273
+ case Icon.Failure:
274
+ return `
275
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
276
+ <line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
277
+ </svg>`;
278
+ case Icon.Warning:
279
+ return `
280
+ <svg class="svg_Warning" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
281
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line>
282
+ </svg>`;
283
+ break;
284
+ case Icon.Example:
285
+ return `
286
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
287
+ <line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line>
288
+ </svg>`;
289
+ default:
290
+ console.error('Invalid icon:', icon);
291
+ }
292
+ }</script>
293
+
294
+ </html>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Obsidian
5
+ VERSION = "1.1.2"
6
+ end
7
+ end