commonmeta-ruby 3.7.1 → 3.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publish.yml +23 -0
  3. data/Gemfile.lock +26 -26
  4. data/bin/commonmeta +1 -1
  5. data/docs/.gitignore +1 -0
  6. data/docs/_publish.yml +4 -0
  7. data/docs/_quarto.yml +46 -0
  8. data/docs/_site/favicon.ico +0 -0
  9. data/docs/_site/images/icon.png +0 -0
  10. data/docs/_site/index.html +947 -0
  11. data/docs/_site/readers/bibtex_reader.html +802 -0
  12. data/docs/_site/search.json +74 -0
  13. data/docs/_site/site_libs/bootstrap/bootstrap-dark.min.css +9 -0
  14. data/docs/_site/site_libs/bootstrap/bootstrap-icons.css +2078 -0
  15. data/docs/_site/site_libs/bootstrap/bootstrap-icons.woff +0 -0
  16. data/docs/_site/site_libs/bootstrap/bootstrap.min.css +9 -0
  17. data/docs/_site/site_libs/bootstrap/bootstrap.min.js +7 -0
  18. data/docs/_site/site_libs/clipboard/clipboard.min.js +7 -0
  19. data/docs/_site/site_libs/quarto-html/anchor.min.js +9 -0
  20. data/docs/_site/site_libs/quarto-html/popper.min.js +6 -0
  21. data/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting-dark.css +179 -0
  22. data/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting.css +179 -0
  23. data/docs/_site/site_libs/quarto-html/quarto.js +889 -0
  24. data/docs/_site/site_libs/quarto-html/tippy.css +1 -0
  25. data/docs/_site/site_libs/quarto-html/tippy.umd.min.js +2 -0
  26. data/docs/_site/site_libs/quarto-nav/headroom.min.js +7 -0
  27. data/docs/_site/site_libs/quarto-nav/quarto-nav.js +288 -0
  28. data/docs/_site/site_libs/quarto-search/autocomplete.umd.js +3 -0
  29. data/docs/_site/site_libs/quarto-search/fuse.min.js +9 -0
  30. data/docs/_site/site_libs/quarto-search/quarto-search.js +1241 -0
  31. data/docs/_site/utils/doi_utils.html +787 -0
  32. data/docs/_site/writers/bibtex_writer.html +803 -0
  33. data/docs/favicon.ico +0 -0
  34. data/docs/images/icon.png +0 -0
  35. data/docs/index.qmd +83 -0
  36. data/docs/readers/bibtex_reader.ipynb +37 -0
  37. data/docs/theme.scss +7 -0
  38. data/docs/utils/doi_utils.ipynb +28 -0
  39. data/docs/writers/bibtex_writer.ipynb +39 -0
  40. data/lib/commonmeta/cli.rb +8 -8
  41. data/lib/commonmeta/readers/json_feed_reader.rb +6 -6
  42. data/lib/commonmeta/utils.rb +2 -2
  43. data/lib/commonmeta/version.rb +1 -1
  44. data/spec/cli_spec.rb +5 -5
  45. data/spec/fixtures/vcr_cassettes/Commonmeta_CLI/json_feed/json_feed_blog_slug.yml +71 -0
  46. data/spec/fixtures/vcr_cassettes/Commonmeta_CLI/json_feed/json_feed_updated.yml +186 -0
  47. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed/updated_posts.yml +186 -0
  48. data/spec/readers/json_feed_reader_spec.rb +5 -5
  49. metadata +42 -5
  50. data/spec/fixtures/vcr_cassettes/Commonmeta_CLI/json_feed/json_feed_not_indexed.yml +0 -37
  51. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed/not_indexed_posts.yml +0 -37
@@ -0,0 +1,787 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
+
4
+ <meta charset="utf-8">
5
+ <meta name="generator" content="quarto-1.4.504">
6
+
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
+
9
+
10
+ <title>commonmeta-ruby - doi_utils</title>
11
+ <style>
12
+ code{white-space: pre-wrap;}
13
+ span.smallcaps{font-variant: small-caps;}
14
+ div.columns{display: flex; gap: min(4vw, 1.5em);}
15
+ div.column{flex: auto; overflow-x: auto;}
16
+ div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17
+ ul.task-list{list-style: none;}
18
+ ul.task-list li input[type="checkbox"] {
19
+ width: 0.8em;
20
+ margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
21
+ vertical-align: middle;
22
+ }
23
+ </style>
24
+
25
+
26
+ <script src="../site_libs/quarto-nav/quarto-nav.js"></script>
27
+ <script src="../site_libs/quarto-nav/headroom.min.js"></script>
28
+ <script src="../site_libs/clipboard/clipboard.min.js"></script>
29
+ <script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
30
+ <script src="../site_libs/quarto-search/fuse.min.js"></script>
31
+ <script src="../site_libs/quarto-search/quarto-search.js"></script>
32
+ <meta name="quarto:offset" content="../">
33
+ <link href="../favicon.ico" rel="icon">
34
+ <script src="../site_libs/quarto-html/quarto.js"></script>
35
+ <script src="../site_libs/quarto-html/popper.min.js"></script>
36
+ <script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
37
+ <script src="../site_libs/quarto-html/anchor.min.js"></script>
38
+ <link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
39
+ <link href="../site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
40
+ <link href="../site_libs/quarto-html/quarto-syntax-highlighting-dark.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
41
+ <script src="../site_libs/bootstrap/bootstrap.min.js"></script>
42
+ <link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
43
+ <link href="../site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
44
+ <link href="../site_libs/bootstrap/bootstrap-dark.min.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
45
+ <script id="quarto-search-options" type="application/json">{
46
+ "location": "navbar",
47
+ "copy-button": false,
48
+ "collapse-after": 3,
49
+ "panel-placement": "end",
50
+ "type": "overlay",
51
+ "limit": 50,
52
+ "keyboard-shortcut": [
53
+ "f",
54
+ "/",
55
+ "s"
56
+ ],
57
+ "show-item-context": false,
58
+ "language": {
59
+ "search-no-results-text": "No results",
60
+ "search-matching-documents-text": "matching documents",
61
+ "search-copy-link-title": "Copy link to search",
62
+ "search-hide-matches-text": "Hide additional matches",
63
+ "search-more-match-text": "more match in this document",
64
+ "search-more-matches-text": "more matches in this document",
65
+ "search-clear-button-title": "Clear",
66
+ "search-detached-cancel-button-title": "Cancel",
67
+ "search-submit-button-title": "Submit",
68
+ "search-label": "Search"
69
+ }
70
+ }</script>
71
+
72
+
73
+ </head>
74
+
75
+ <body class="nav-sidebar floating nav-fixed">
76
+
77
+ <div id="quarto-search-results"></div>
78
+ <header id="quarto-header" class="headroom fixed-top">
79
+ <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
80
+ <div class="navbar-container container-fluid">
81
+ <div class="navbar-brand-container mx-auto">
82
+ <a href="../index.html" class="navbar-brand navbar-brand-logo">
83
+ <img src="../images/icon.png" alt="commonmeta-py" class="navbar-logo">
84
+ </a>
85
+ <a class="navbar-brand" href="../index.html">
86
+ <span class="navbar-title">commonmeta-ruby</span>
87
+ </a>
88
+ </div>
89
+ <div id="quarto-search" class="" title="Search"></div>
90
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
91
+ <span class="navbar-toggler-icon"></span>
92
+ </button>
93
+ <div class="collapse navbar-collapse" id="navbarCollapse">
94
+ <ul class="navbar-nav navbar-nav-scroll ms-auto">
95
+ <li class="nav-item compact">
96
+ <a class="nav-link" href="https://github.com/front-matter/commonmeta-ruby"> <i class="bi bi-github" role="img">
97
+ </i>
98
+ <span class="menu-text"></span></a>
99
+ </li>
100
+ </ul>
101
+ </div> <!-- /navcollapse -->
102
+ <div class="quarto-navbar-tools">
103
+ <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
104
+ </div>
105
+ </div> <!-- /container-fluid -->
106
+ </nav>
107
+ <nav class="quarto-secondary-nav">
108
+ <div class="container-fluid d-flex">
109
+ <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
110
+ <i class="bi bi-layout-text-sidebar-reverse"></i>
111
+ </button>
112
+ <a class="flex-grow-1 no-decor" role="button" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
113
+ <h1 class="quarto-secondary-nav-title">doi_utils</h1>
114
+ </a>
115
+ </div>
116
+ </nav>
117
+ </header>
118
+ <!-- content -->
119
+ <div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
120
+ <!-- sidebar -->
121
+ <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto">
122
+ <div class="sidebar-menu-container">
123
+ <ul class="list-unstyled mt-1">
124
+ <li class="sidebar-item">
125
+ <div class="sidebar-item-container">
126
+ <a href="../index.html" class="sidebar-item-text sidebar-link">
127
+ <span class="menu-text">Guide</span></a>
128
+ </div>
129
+ </li>
130
+ <li class="sidebar-item sidebar-item-section">
131
+ <div class="sidebar-item-container">
132
+ <a class="sidebar-item-text sidebar-link text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" aria-expanded="true">
133
+ <span class="menu-text">Readers</span></a>
134
+ <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" aria-expanded="true" aria-label="Toggle section">
135
+ <i class="bi bi-chevron-right ms-2"></i>
136
+ </a>
137
+ </div>
138
+ <ul id="quarto-sidebar-section-1" class="collapse list-unstyled sidebar-section depth1 show">
139
+ <li class="sidebar-item">
140
+ <div class="sidebar-item-container">
141
+ <a href="../readers/bibtex_reader.html" class="sidebar-item-text sidebar-link">
142
+ <span class="menu-text">BibTex Reader</span></a>
143
+ </div>
144
+ </li>
145
+ </ul>
146
+ </li>
147
+ <li class="sidebar-item sidebar-item-section">
148
+ <div class="sidebar-item-container">
149
+ <a class="sidebar-item-text sidebar-link text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" aria-expanded="true">
150
+ <span class="menu-text">Writers</span></a>
151
+ <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" aria-expanded="true" aria-label="Toggle section">
152
+ <i class="bi bi-chevron-right ms-2"></i>
153
+ </a>
154
+ </div>
155
+ <ul id="quarto-sidebar-section-2" class="collapse list-unstyled sidebar-section depth1 show">
156
+ <li class="sidebar-item">
157
+ <div class="sidebar-item-container">
158
+ <a href="../writers/bibtex_writer.html" class="sidebar-item-text sidebar-link">
159
+ <span class="menu-text">BibTex Writer</span></a>
160
+ </div>
161
+ </li>
162
+ </ul>
163
+ </li>
164
+ <li class="sidebar-item sidebar-item-section">
165
+ <div class="sidebar-item-container">
166
+ <a class="sidebar-item-text sidebar-link text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" aria-expanded="true">
167
+ <span class="menu-text">Utils</span></a>
168
+ <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" aria-expanded="true" aria-label="Toggle section">
169
+ <i class="bi bi-chevron-right ms-2"></i>
170
+ </a>
171
+ </div>
172
+ <ul id="quarto-sidebar-section-3" class="collapse list-unstyled sidebar-section depth1 show">
173
+ <li class="sidebar-item">
174
+ <div class="sidebar-item-container">
175
+ <a href="../utils/doi_utils.html" class="sidebar-item-text sidebar-link active">
176
+ <span class="menu-text">doi_utils</span></a>
177
+ </div>
178
+ </li>
179
+ </ul>
180
+ </li>
181
+ </ul>
182
+ </div>
183
+ </nav>
184
+ <div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
185
+ <!-- margin-sidebar -->
186
+ <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
187
+
188
+ </div>
189
+ <!-- main -->
190
+ <main class="content" id="quarto-document-content">
191
+
192
+ <header id="title-block-header" class="quarto-title-block default">
193
+ <div class="quarto-title">
194
+ <h1 class="title d-none d-lg-block">doi_utils</h1>
195
+ </div>
196
+
197
+
198
+
199
+ <div class="quarto-title-meta">
200
+
201
+
202
+
203
+
204
+ </div>
205
+
206
+
207
+
208
+ </header>
209
+
210
+
211
+
212
+
213
+
214
+ </main> <!-- /main -->
215
+ <script id="quarto-html-after-body" type="application/javascript">
216
+ window.document.addEventListener("DOMContentLoaded", function (event) {
217
+ const toggleBodyColorMode = (bsSheetEl) => {
218
+ const mode = bsSheetEl.getAttribute("data-mode");
219
+ const bodyEl = window.document.querySelector("body");
220
+ if (mode === "dark") {
221
+ bodyEl.classList.add("quarto-dark");
222
+ bodyEl.classList.remove("quarto-light");
223
+ } else {
224
+ bodyEl.classList.add("quarto-light");
225
+ bodyEl.classList.remove("quarto-dark");
226
+ }
227
+ }
228
+ const toggleBodyColorPrimary = () => {
229
+ const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
230
+ if (bsSheetEl) {
231
+ toggleBodyColorMode(bsSheetEl);
232
+ }
233
+ }
234
+ toggleBodyColorPrimary();
235
+ const disableStylesheet = (stylesheets) => {
236
+ for (let i=0; i < stylesheets.length; i++) {
237
+ const stylesheet = stylesheets[i];
238
+ stylesheet.rel = 'prefetch';
239
+ }
240
+ }
241
+ const enableStylesheet = (stylesheets) => {
242
+ for (let i=0; i < stylesheets.length; i++) {
243
+ const stylesheet = stylesheets[i];
244
+ stylesheet.rel = 'stylesheet';
245
+ }
246
+ }
247
+ const manageTransitions = (selector, allowTransitions) => {
248
+ const els = window.document.querySelectorAll(selector);
249
+ for (let i=0; i < els.length; i++) {
250
+ const el = els[i];
251
+ if (allowTransitions) {
252
+ el.classList.remove('notransition');
253
+ } else {
254
+ el.classList.add('notransition');
255
+ }
256
+ }
257
+ }
258
+ const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
259
+ const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
260
+ const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
261
+ let newTheme = '';
262
+ if(darkModeDefault) {
263
+ newTheme = isAlternate ? baseTheme : alternateTheme;
264
+ } else {
265
+ newTheme = isAlternate ? alternateTheme : baseTheme;
266
+ }
267
+ const changeGiscusTheme = () => {
268
+ // From: https://github.com/giscus/giscus/issues/336
269
+ const sendMessage = (message) => {
270
+ const iframe = document.querySelector('iframe.giscus-frame');
271
+ if (!iframe) return;
272
+ iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
273
+ }
274
+ sendMessage({
275
+ setConfig: {
276
+ theme: newTheme
277
+ }
278
+ });
279
+ }
280
+ const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
281
+ if (isGiscussLoaded) {
282
+ changeGiscusTheme();
283
+ }
284
+ }
285
+ const toggleColorMode = (alternate) => {
286
+ // Switch the stylesheets
287
+ const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
288
+ manageTransitions('#quarto-margin-sidebar .nav-link', false);
289
+ if (alternate) {
290
+ enableStylesheet(alternateStylesheets);
291
+ for (const sheetNode of alternateStylesheets) {
292
+ if (sheetNode.id === "quarto-bootstrap") {
293
+ toggleBodyColorMode(sheetNode);
294
+ }
295
+ }
296
+ } else {
297
+ disableStylesheet(alternateStylesheets);
298
+ toggleBodyColorPrimary();
299
+ }
300
+ manageTransitions('#quarto-margin-sidebar .nav-link', true);
301
+ // Switch the toggles
302
+ const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
303
+ for (let i=0; i < toggles.length; i++) {
304
+ const toggle = toggles[i];
305
+ if (toggle) {
306
+ if (alternate) {
307
+ toggle.classList.add("alternate");
308
+ } else {
309
+ toggle.classList.remove("alternate");
310
+ }
311
+ }
312
+ }
313
+ // Hack to workaround the fact that safari doesn't
314
+ // properly recolor the scrollbar when toggling (#1455)
315
+ if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
316
+ manageTransitions("body", false);
317
+ window.scrollTo(0, 1);
318
+ setTimeout(() => {
319
+ window.scrollTo(0, 0);
320
+ manageTransitions("body", true);
321
+ }, 40);
322
+ }
323
+ }
324
+ const isFileUrl = () => {
325
+ return window.location.protocol === 'file:';
326
+ }
327
+ const hasAlternateSentinel = () => {
328
+ let styleSentinel = getColorSchemeSentinel();
329
+ if (styleSentinel !== null) {
330
+ return styleSentinel === "alternate";
331
+ } else {
332
+ return false;
333
+ }
334
+ }
335
+ const setStyleSentinel = (alternate) => {
336
+ const value = alternate ? "alternate" : "default";
337
+ if (!isFileUrl()) {
338
+ window.localStorage.setItem("quarto-color-scheme", value);
339
+ } else {
340
+ localAlternateSentinel = value;
341
+ }
342
+ }
343
+ const getColorSchemeSentinel = () => {
344
+ if (!isFileUrl()) {
345
+ const storageValue = window.localStorage.getItem("quarto-color-scheme");
346
+ return storageValue != null ? storageValue : localAlternateSentinel;
347
+ } else {
348
+ return localAlternateSentinel;
349
+ }
350
+ }
351
+ const darkModeDefault = false;
352
+ let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
353
+ // Dark / light mode switch
354
+ window.quartoToggleColorScheme = () => {
355
+ // Read the current dark / light value
356
+ let toAlternate = !hasAlternateSentinel();
357
+ toggleColorMode(toAlternate);
358
+ setStyleSentinel(toAlternate);
359
+ toggleGiscusIfUsed(toAlternate, darkModeDefault);
360
+ };
361
+ // Ensure there is a toggle, if there isn't float one in the top right
362
+ if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
363
+ const a = window.document.createElement('a');
364
+ a.classList.add('top-right');
365
+ a.classList.add('quarto-color-scheme-toggle');
366
+ a.href = "";
367
+ a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
368
+ const i = window.document.createElement("i");
369
+ i.classList.add('bi');
370
+ a.appendChild(i);
371
+ window.document.body.appendChild(a);
372
+ }
373
+ // Switch to dark mode if need be
374
+ if (hasAlternateSentinel()) {
375
+ toggleColorMode(true);
376
+ } else {
377
+ toggleColorMode(false);
378
+ }
379
+ const icon = "";
380
+ const anchorJS = new window.AnchorJS();
381
+ anchorJS.options = {
382
+ placement: 'right',
383
+ icon: icon
384
+ };
385
+ anchorJS.add('.anchored');
386
+ const isCodeAnnotation = (el) => {
387
+ for (const clz of el.classList) {
388
+ if (clz.startsWith('code-annotation-')) {
389
+ return true;
390
+ }
391
+ }
392
+ return false;
393
+ }
394
+ const clipboard = new window.ClipboardJS('.code-copy-button', {
395
+ text: function(trigger) {
396
+ const codeEl = trigger.previousElementSibling.cloneNode(true);
397
+ for (const childEl of codeEl.children) {
398
+ if (isCodeAnnotation(childEl)) {
399
+ childEl.remove();
400
+ }
401
+ }
402
+ return codeEl.innerText;
403
+ }
404
+ });
405
+ clipboard.on('success', function(e) {
406
+ // button target
407
+ const button = e.trigger;
408
+ // don't keep focus
409
+ button.blur();
410
+ // flash "checked"
411
+ button.classList.add('code-copy-button-checked');
412
+ var currentTitle = button.getAttribute("title");
413
+ button.setAttribute("title", "Copied!");
414
+ let tooltip;
415
+ if (window.bootstrap) {
416
+ button.setAttribute("data-bs-toggle", "tooltip");
417
+ button.setAttribute("data-bs-placement", "left");
418
+ button.setAttribute("data-bs-title", "Copied!");
419
+ tooltip = new bootstrap.Tooltip(button,
420
+ { trigger: "manual",
421
+ customClass: "code-copy-button-tooltip",
422
+ offset: [0, -8]});
423
+ tooltip.show();
424
+ }
425
+ setTimeout(function() {
426
+ if (tooltip) {
427
+ tooltip.hide();
428
+ button.removeAttribute("data-bs-title");
429
+ button.removeAttribute("data-bs-toggle");
430
+ button.removeAttribute("data-bs-placement");
431
+ }
432
+ button.setAttribute("title", currentTitle);
433
+ button.classList.remove('code-copy-button-checked');
434
+ }, 1000);
435
+ // clear code selection
436
+ e.clearSelection();
437
+ });
438
+ function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
439
+ const config = {
440
+ allowHTML: true,
441
+ maxWidth: 500,
442
+ delay: 100,
443
+ arrow: false,
444
+ appendTo: function(el) {
445
+ return el.parentElement;
446
+ },
447
+ interactive: true,
448
+ interactiveBorder: 10,
449
+ theme: 'quarto',
450
+ placement: 'bottom-start',
451
+ };
452
+ if (contentFn) {
453
+ config.content = contentFn;
454
+ }
455
+ if (onTriggerFn) {
456
+ config.onTrigger = onTriggerFn;
457
+ }
458
+ if (onUntriggerFn) {
459
+ config.onUntrigger = onUntriggerFn;
460
+ }
461
+ window.tippy(el, config);
462
+ }
463
+ const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
464
+ for (var i=0; i<noterefs.length; i++) {
465
+ const ref = noterefs[i];
466
+ tippyHover(ref, function() {
467
+ // use id or data attribute instead here
468
+ let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
469
+ try { href = new URL(href).hash; } catch {}
470
+ const id = href.replace(/^#\/?/, "");
471
+ const note = window.document.getElementById(id);
472
+ return note.innerHTML;
473
+ });
474
+ }
475
+ const xrefs = window.document.querySelectorAll('a.quarto-xref');
476
+ const processXRef = (id, note) => {
477
+ // Strip column container classes
478
+ const stripColumnClz = (el) => {
479
+ el.classList.remove("page-full", "page-columns");
480
+ if (el.children) {
481
+ for (const child of el.children) {
482
+ stripColumnClz(child);
483
+ }
484
+ }
485
+ }
486
+ stripColumnClz(note)
487
+ const typesetMath = (el) => {
488
+ if (window.MathJax) {
489
+ // MathJax Typeset
490
+ window.MathJax.typeset([el]);
491
+ } else if (window.katex) {
492
+ // KaTeX Render
493
+ var mathElements = el.getElementsByClassName("math");
494
+ var macros = [];
495
+ for (var i = 0; i < mathElements.length; i++) {
496
+ var texText = mathElements[i].firstChild;
497
+ if (mathElements[i].tagName == "SPAN") {
498
+ window.katex.render(texText.data, mathElements[i], {
499
+ displayMode: mathElements[i].classList.contains('display'),
500
+ throwOnError: false,
501
+ macros: macros,
502
+ fleqn: false
503
+ });
504
+ }
505
+ }
506
+ }
507
+ }
508
+ if (id === null || id.startsWith('sec-')) {
509
+ // Special case sections, only their first couple elements
510
+ const container = document.createElement("div");
511
+ if (note.children && note.children.length > 2) {
512
+ container.appendChild(note.children[0].cloneNode(true));
513
+ for (let i = 1; i < note.children.length; i++) {
514
+ const child = note.children[i];
515
+ if (child.tagName === "P" && child.innerText === "") {
516
+ continue;
517
+ } else {
518
+ container.appendChild(child.cloneNode(true));
519
+ break;
520
+ }
521
+ }
522
+ typesetMath(container);
523
+ return container.innerHTML
524
+ } else {
525
+ typesetMath(note);
526
+ return note.innerHTML;
527
+ }
528
+ } else {
529
+ // Remove any anchor links if they are present
530
+ const anchorLink = note.querySelector('a.anchorjs-link');
531
+ if (anchorLink) {
532
+ anchorLink.remove();
533
+ }
534
+ typesetMath(note);
535
+ return note.innerHTML;
536
+ }
537
+ }
538
+ for (var i=0; i<xrefs.length; i++) {
539
+ const xref = xrefs[i];
540
+ tippyHover(xref, undefined, function(instance) {
541
+ instance.disable();
542
+ let url = xref.getAttribute('href');
543
+ let hash = undefined;
544
+ if (url.startsWith('#')) {
545
+ hash = url;
546
+ } else {
547
+ try { hash = new URL(url).hash; } catch {}
548
+ }
549
+ if (hash) {
550
+ const id = hash.replace(/^#\/?/, "");
551
+ const note = window.document.getElementById(id);
552
+ if (note !== null) {
553
+ try {
554
+ const html = processXRef(id, note.cloneNode(true));
555
+ instance.setContent(html);
556
+ } finally {
557
+ instance.enable();
558
+ instance.show();
559
+ }
560
+ } else {
561
+ // See if we can fetch this
562
+ fetch(url.split('#')[0])
563
+ .then(res => res.text())
564
+ .then(html => {
565
+ const parser = new DOMParser();
566
+ const htmlDoc = parser.parseFromString(html, "text/html");
567
+ const note = htmlDoc.getElementById(id);
568
+ if (note !== null) {
569
+ const html = processXRef(id, note);
570
+ instance.setContent(html);
571
+ }
572
+ }).finally(() => {
573
+ instance.enable();
574
+ instance.show();
575
+ });
576
+ }
577
+ } else {
578
+ // See if we can fetch a full url (with no hash to target)
579
+ // This is a special case and we should probably do some content thinning / targeting
580
+ fetch(url)
581
+ .then(res => res.text())
582
+ .then(html => {
583
+ const parser = new DOMParser();
584
+ const htmlDoc = parser.parseFromString(html, "text/html");
585
+ const note = htmlDoc.querySelector('main.content');
586
+ if (note !== null) {
587
+ // This should only happen for chapter cross references
588
+ // (since there is no id in the URL)
589
+ // remove the first header
590
+ if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
591
+ note.children[0].remove();
592
+ }
593
+ const html = processXRef(null, note);
594
+ instance.setContent(html);
595
+ }
596
+ }).finally(() => {
597
+ instance.enable();
598
+ instance.show();
599
+ });
600
+ }
601
+ }, function(instance) {
602
+ });
603
+ }
604
+ let selectedAnnoteEl;
605
+ const selectorForAnnotation = ( cell, annotation) => {
606
+ let cellAttr = 'data-code-cell="' + cell + '"';
607
+ let lineAttr = 'data-code-annotation="' + annotation + '"';
608
+ const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
609
+ return selector;
610
+ }
611
+ const selectCodeLines = (annoteEl) => {
612
+ const doc = window.document;
613
+ const targetCell = annoteEl.getAttribute("data-target-cell");
614
+ const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
615
+ const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
616
+ const lines = annoteSpan.getAttribute("data-code-lines").split(",");
617
+ const lineIds = lines.map((line) => {
618
+ return targetCell + "-" + line;
619
+ })
620
+ let top = null;
621
+ let height = null;
622
+ let parent = null;
623
+ if (lineIds.length > 0) {
624
+ //compute the position of the single el (top and bottom and make a div)
625
+ const el = window.document.getElementById(lineIds[0]);
626
+ top = el.offsetTop;
627
+ height = el.offsetHeight;
628
+ parent = el.parentElement.parentElement;
629
+ if (lineIds.length > 1) {
630
+ const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
631
+ const bottom = lastEl.offsetTop + lastEl.offsetHeight;
632
+ height = bottom - top;
633
+ }
634
+ if (top !== null && height !== null && parent !== null) {
635
+ // cook up a div (if necessary) and position it
636
+ let div = window.document.getElementById("code-annotation-line-highlight");
637
+ if (div === null) {
638
+ div = window.document.createElement("div");
639
+ div.setAttribute("id", "code-annotation-line-highlight");
640
+ div.style.position = 'absolute';
641
+ parent.appendChild(div);
642
+ }
643
+ div.style.top = top - 2 + "px";
644
+ div.style.height = height + 4 + "px";
645
+ div.style.left = 0;
646
+ let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
647
+ if (gutterDiv === null) {
648
+ gutterDiv = window.document.createElement("div");
649
+ gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
650
+ gutterDiv.style.position = 'absolute';
651
+ const codeCell = window.document.getElementById(targetCell);
652
+ const gutter = codeCell.querySelector('.code-annotation-gutter');
653
+ gutter.appendChild(gutterDiv);
654
+ }
655
+ gutterDiv.style.top = top - 2 + "px";
656
+ gutterDiv.style.height = height + 4 + "px";
657
+ }
658
+ selectedAnnoteEl = annoteEl;
659
+ }
660
+ };
661
+ const unselectCodeLines = () => {
662
+ const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
663
+ elementsIds.forEach((elId) => {
664
+ const div = window.document.getElementById(elId);
665
+ if (div) {
666
+ div.remove();
667
+ }
668
+ });
669
+ selectedAnnoteEl = undefined;
670
+ };
671
+ // Handle positioning of the toggle
672
+ window.addEventListener(
673
+ "resize",
674
+ throttle(() => {
675
+ elRect = undefined;
676
+ if (selectedAnnoteEl) {
677
+ selectCodeLines(selectedAnnoteEl);
678
+ }
679
+ }, 10)
680
+ );
681
+ function throttle(fn, ms) {
682
+ let throttle = false;
683
+ let timer;
684
+ return (...args) => {
685
+ if(!throttle) { // first call gets through
686
+ fn.apply(this, args);
687
+ throttle = true;
688
+ } else { // all the others get throttled
689
+ if(timer) clearTimeout(timer); // cancel #2
690
+ timer = setTimeout(() => {
691
+ fn.apply(this, args);
692
+ timer = throttle = false;
693
+ }, ms);
694
+ }
695
+ };
696
+ }
697
+ // Attach click handler to the DT
698
+ const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
699
+ for (const annoteDlNode of annoteDls) {
700
+ annoteDlNode.addEventListener('click', (event) => {
701
+ const clickedEl = event.target;
702
+ if (clickedEl !== selectedAnnoteEl) {
703
+ unselectCodeLines();
704
+ const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
705
+ if (activeEl) {
706
+ activeEl.classList.remove('code-annotation-active');
707
+ }
708
+ selectCodeLines(clickedEl);
709
+ clickedEl.classList.add('code-annotation-active');
710
+ } else {
711
+ // Unselect the line
712
+ unselectCodeLines();
713
+ clickedEl.classList.remove('code-annotation-active');
714
+ }
715
+ });
716
+ }
717
+ const findCites = (el) => {
718
+ const parentEl = el.parentElement;
719
+ if (parentEl) {
720
+ const cites = parentEl.dataset.cites;
721
+ if (cites) {
722
+ return {
723
+ el,
724
+ cites: cites.split(' ')
725
+ };
726
+ } else {
727
+ return findCites(el.parentElement)
728
+ }
729
+ } else {
730
+ return undefined;
731
+ }
732
+ };
733
+ var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
734
+ for (var i=0; i<bibliorefs.length; i++) {
735
+ const ref = bibliorefs[i];
736
+ const citeInfo = findCites(ref);
737
+ if (citeInfo) {
738
+ tippyHover(citeInfo.el, function() {
739
+ var popup = window.document.createElement('div');
740
+ citeInfo.cites.forEach(function(cite) {
741
+ var citeDiv = window.document.createElement('div');
742
+ citeDiv.classList.add('hanging-indent');
743
+ citeDiv.classList.add('csl-entry');
744
+ var biblioDiv = window.document.getElementById('ref-' + cite);
745
+ if (biblioDiv) {
746
+ citeDiv.innerHTML = biblioDiv.innerHTML;
747
+ }
748
+ popup.appendChild(citeDiv);
749
+ });
750
+ return popup.innerHTML;
751
+ });
752
+ }
753
+ }
754
+ });
755
+ </script>
756
+ </div> <!-- /content -->
757
+ <footer class="footer">
758
+ <div class="nav-footer">
759
+ <div class="nav-footer-left">
760
+ <p>Copyright ©2023 Front Matter.</p>
761
+ </div>
762
+ <div class="nav-footer-center">
763
+ &nbsp;
764
+ </div>
765
+ <div class="nav-footer-right">
766
+ <ul class="footer-items list-unstyled">
767
+ <li class="nav-item compact">
768
+ <a class="nav-link" href="mailto:info@front-matter.io">
769
+ <i class="bi bi-envelope" role="img">
770
+ </i>
771
+ </a>
772
+ </li>
773
+ <li class="nav-item compact">
774
+ <a class="nav-link" href="https://rogue-scholar.social/@admin">
775
+ <i class="bi bi-mastodon" role="img">
776
+ </i>
777
+ </a>
778
+ </li>
779
+ </ul>
780
+ </div>
781
+ </div>
782
+ </footer>
783
+
784
+
785
+
786
+
787
+ </body></html>