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.9.37"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9 10<title>Johannes Feldhege, M.Sc. B.A. â Johannes Feldhege</title> 11<style> 12/* Default styles provided by pandoc. 13** See https://pandoc.org/MANUAL.html#variables-for-html for config info. 14*/ 15code{white-space: pre-wrap;} 16span.smallcaps{font-variant: small-caps;} 17div.columns{display: flex; gap: min(4vw, 1.5em);} 18div.column{flex: auto; overflow-x: auto;} 19div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 20ul.task-list{list-style: none;} 21ul.task-list li input[type="checkbox"] { 22 width: 0.8em; 23 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 24 vertical-align: middle; 25} 26</style> 27 28
29<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 32
32
33<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-search/quarto-search.js"></script>
34 35<meta name="quarto:offset" content="./"> 36<link href="./assets/logo.png" rel="icon" type="image/png">
37<script src="site_libs/cookie-consent/cookie-consent.js"></script>
37 38<link href="site_libs/cookie-consent/cookie-consent.css" rel="stylesheet">
39<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 39
39
40<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 40
40
41<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 41
41
42<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
42 43<link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> 44<link href="site_libs/quarto-html/quarto-syntax-highlighting-3b5aaf7f86bad49ac49ec71cebff2afb.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles"> 45<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark-8f6e9aadc5ea5a3b74645e22aaa20220.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles"> 46<link href="site_libs/quarto-html/quarto-syntax-highlighting-3b5aaf7f86bad49ac49ec71cebff2afb.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
47<script src="site_libs/bootstrap/bootstrap.min.js"></script>
47 48<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 49<link href="site_libs/bootstrap/bootstrap-016a33c344d85df288a4ca5657a8314d.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light"> 50<link href="site_libs/bootstrap/bootstrap-dark-8dbb7b7b978eae176009dfa8cc82e56a.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark"> 51<link href="site_libs/bootstrap/bootstrap-016a33c344d85df288a4ca5657a8314d.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light"> 52<link href="site_libs/quarto-contrib/fontawesome6-0.1.0/all.css" rel="stylesheet"> 53<link href="site_libs/quarto-contrib/fontawesome6-0.1.0/latex-fontsize.css" rel="stylesheet"> 54<link href="site_libs/quarto-contrib/academicons-1.9.2/all.css" rel="stylesheet"> 55<link href="site_libs/quarto-contrib/academicons-1.9.2/size.css" rel="stylesheet">
56<script id="quarto-search-options" type="application/json">{ 57 "location": "navbar", 58 "copy-button": false, 59 "collapse-after": 3, 60 "panel-placement": "end", 61 "type": "overlay", 62 "limit": 50, 63 "keyboard-shortcut": [ 64 "f", 65 "/", 66 "s" 67 ], 68 "show-item-context": false, 69 "language": { 70 "search-no-results-text": "No results", 71 "search-matching-documents-text": "matching documents", 72 "search-copy-link-title": "Copy link to search", 73 "search-hide-matches-text": "Hide additional matches", 74 "search-more-match-text": "more match in this document", 75 "search-more-matches-text": "more matches in this document", 76 "search-clear-button-title": "Clear", 77 "search-text-placeholder": "", 78 "search-detached-cancel-button-title": "Cancel", 79 "search-submit-button-title": "Submit", 80 "search-label": "Search" 81 } 82}</script>
82 83
84<script type="text/javascript" charset="UTF-8"> 85document.addEventListener('DOMContentLoaded', function () { 86cookieconsent.run({ 87 "notice_banner_type":"headline", 88 "consent_type":"express", 89 "palette":"light", 90 "language":"en", 91 "page_load_consent_levels":["strictly-necessary"], 92 "notice_banner_reject_button_hide":false, 93 "preferences_center_close_button_hide":false, 94 "website_name":"" 95 , 96"language":"en" 97 }); 98}); 99</script>
99 100 101 102 103<meta property="og:title" content="Johannes Feldhege, M.Sc. B.A. â Johannes Feldhege"> 104<meta property="og:description" content="Persönliche Webseite von Johannes Feldhege"> 105<meta property="og:site_name" content="Johannes Feldhege"> 106</head> 107 108<body class="nav-fixed quarto-light">
108<script id="quarto-html-before-body" type="application/javascript"> 109 const toggleBodyColorMode = (bsSheetEl) => { 110 const mode = bsSheetEl.getAttribute("data-mode"); 111 const bodyEl = window.document.querySelector("body"); 112 if (mode === "dark") { 113 bodyEl.classList.add("quarto-dark"); 114 bodyEl.classList.remove("quarto-light"); 115 } else { 116 bodyEl.classList.add("quarto-light"); 117 bodyEl.classList.remove("quarto-dark"); 118 } 119 } 120 const toggleBodyColorPrimary = () => { 121 const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])"); 122 if (bsSheetEl) { 123 toggleBodyColorMode(bsSheetEl); 124 } 125 } 126 const setColorSchemeToggle = (alternate) => { 127 const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle'); 128 for (let i=0; i < toggles.length; i++) { 129 const toggle = toggles[i]; 130 if (toggle) { 131 if (alternate) { 132 toggle.classList.add("alternate"); 133 } else { 134 toggle.classList.remove("alternate"); 135 } 136 } 137 } 138 }; 139 const toggleColorMode = (alternate) => { 140 // Switch the stylesheets 141 const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)'); 142 const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate'); 143 manageTransitions('#quarto-margin-sidebar .nav-link', false); 144 if (alternate) { 145 // note: dark is layered on light, we don't disable primary! 146 enableStylesheet(alternateStylesheets); 147 for (const sheetNode of alternateStylesheets) { 148 if (sheetNode.id === "quarto-bootstrap") { 149 toggleBodyColorMode(sheetNode); 150 } 151 } 152 } else { 153 disableStylesheet(alternateStylesheets); 154 enableStylesheet(primaryStylesheets) 155 toggleBodyColorPrimary(); 156 } 157 manageTransitions('#quarto-margin-sidebar .nav-link', true); 158 // Switch the toggles 159 setColorSchemeToggle(alternate) 160 // Hack to workaround the fact that safari doesn't 161 // properly recolor the scrollbar when toggling (#1455) 162 if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) { 163 manageTransitions("body", false); 164 window.scrollTo(0, 1); 165 setTimeout(() => { 166 window.scrollTo(0, 0); 167 manageTransitions("body", true); 168 }, 40); 169 } 170 } 171 const disableStylesheet = (stylesheets) => { 172 for (let i=0; i < stylesheets.length; i++) { 173 const stylesheet = stylesheets[i]; 174 stylesheet.rel = 'disabled-stylesheet'; 175 } 176 } 177 const enableStylesheet = (stylesheets) => { 178 for (let i=0; i < stylesheets.length; i++) { 179 const stylesheet = stylesheets[i]; 180 if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check 181 stylesheet.rel = 'stylesheet'; 182 } 183 } 184 } 185 const manageTransitions = (selector, allowTransitions) => { 186 const els = window.document.querySelectorAll(selector); 187 for (let i=0; i < els.length; i++) { 188 const el = els[i]; 189 if (allowTransitions) { 190 el.classList.remove('notransition'); 191 } else { 192 el.classList.add('notransition'); 193 } 194 } 195 } 196 const isFileUrl = () => { 197 return window.location.protocol === 'file:'; 198 } 199 const hasAlternateSentinel = () => { 200 let styleSentinel = getColorSchemeSentinel(); 201 if (styleSentinel !== null) { 202 return styleSentinel === "alternate"; 203 } else { 204 return false; 205 } 206 } 207 const setStyleSentinel = (alternate) => { 208 const value = alternate ? "alternate" : "default"; 209 if (!isFileUrl()) { 210 window.localStorage.setItem("quarto-color-scheme", value); 211 } else { 212 localAlternateSentinel = value; 213 } 214 } 215 const getColorSchemeSentinel = () => { 216 if (!isFileUrl()) { 217 const storageValue = window.localStorage.getItem("quarto-color-scheme"); 218 return storageValue != null ? storageValue : localAlternateSentinel; 219 } else { 220 return localAlternateSentinel; 221 } 222 } 223 const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => { 224 const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light'; 225 const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark'; 226 let newTheme = ''; 227 if(authorPrefersDark) { 228 newTheme = isAlternate ? baseTheme : alternateTheme; 229 } else { 230 newTheme = isAlternate ? alternateTheme : baseTheme; 231 } 232 const changeGiscusTheme = () => { 233 // From: https://github.com/giscus/giscus/issues/336 234 const sendMessage = (message) => { 235 const iframe = document.querySelector('iframe.giscus-frame'); 236 if (!iframe) return; 237 iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app'); 238 } 239 sendMessage({ 240 setConfig: { 241 theme: newTheme 242 } 243 }); 244 } 245 const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null; 246 if (isGiscussLoaded) { 247 changeGiscusTheme(); 248 } 249 }; 250 const authorPrefersDark = false;
251 const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)'); 252 const darkModeDefault = queryPrefersDark.matches; 253 document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet'; 254 document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet'; 255 let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default'; 256 // Dark / light mode switch 257 window.quartoToggleColorScheme = () => { 258 // Read the current dark / light value 259 let toAlternate = !hasAlternateSentinel(); 260 toggleColorMode(toAlternate); 261 setStyleSentinel(toAlternate); 262 toggleGiscusIfUsed(toAlternate, darkModeDefault); 263 window.dispatchEvent(new Event('resize')); 264 }; 265 queryPrefersDark.addEventListener("change", e => { 266 if(window.localStorage.getItem("quarto-color-scheme") !== null) 267 return; 268 const alternate = e.matches 269 toggleColorMode(alternate); 270 localAlternateSentinel = e.matches ? 'alternate' : 'default'; // this is used alongside local storage! 271 toggleGiscusIfUsed(alternate, darkModeDefault); 272 }); 273 // Switch to dark mode if need be 274 if (hasAlternateSentinel()) { 275 toggleColorMode(true); 276 } else { 277 toggleColorMode(false); 278 } 279 </script>
279 280 281<div id="quarto-search-results"></div> 282 <header id="quarto-header" class="headroom fixed-top"> 283 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 284 <div class="navbar-container container-fluid"> 285 <div class="navbar-brand-container mx-auto"> 286 <a href="./index.html" class="navbar-brand navbar-brand-logo"> 287 <img src="./assets/logo.png" alt="" class="navbar-logo light-content"> 288 <img src="./assets/logo.png" alt="" class="navbar-logo dark-content"> 289 </a> 290 <a class="navbar-brand" href="./index.html"> 291 <span class="navbar-title">Johannes Feldhege</span> 292 </a> 293 </div> 294 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> 295 <span class="navbar-toggler-icon"></span> 296</button> 297 <div class="collapse navbar-collapse" id="navbarCollapse"> 298 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 299 <li class="nav-item"> 300 <a class="nav-link active" href="./index.html" aria-current="page"> 301<span class="menu-text">Home</span></a> 302 </li> 303 <li class="nav-item"> 304 <a class="nav-link" href="./publikationen.html"> 305<span class="menu-text">Publikationen</span></a> 306 </li> 307 <li class="nav-item"> 308 <a class="nav-link" href="./cv.html"> 309<span class="menu-text">CV</span></a> 310 </li> 311 <li class="nav-item"> 312 <a class="nav-link" href="./impressum.html"> 313<span class="menu-text">Impressum</span></a> 314 </li> 315 <li class="nav-item compact"> 316 <a class="nav-link" href="https://github.com/jfeldhege/"> <i class="bi bi-github" role="img" aria-label="GitHub Profile"> 317</i> 318<span class="menu-text"></span></a> 319 </li> 320 <li class="nav-item compact"> 321 <a class="nav-link" href="https://www.linkedin.com/in/johannes-feldhege/"> <i class="bi bi-linkedin" role="img" aria-label="Linkedin"> 322</i> 323<span class="menu-text"></span></a> 324 </li> 325 <li class="nav-item"> 326 <a class="nav-link" href="https://scholar.google.com/citations?user=KSmfyO8AAAAJ&hl=de"> 327<span class="menu-text"><i class="ai ai-google-scholar" title="" style="color:"></i></span></a> 328 </li> 329 <li class="nav-item"> 330 <a class="nav-link" href="https://www.researchgate.net/profile/Johannes-Feldhege"> 331<span class="menu-text"><i class="ai ai-researchgate" title="" style="color:"></i></span></a> 332 </li> 333</ul> 334 </div> <!-- /navcollapse --> 335 <div class="quarto-navbar-tools"> 336 <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> 337</div> 338 </div> <!-- /container-fluid --> 339 </nav> 340</header> 341<!-- content --> 342<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar"> 343<!-- sidebar --> 344<!-- margin-sidebar --> 345 346<!-- main --> 347<div class="quarto-about-trestles column-page"> 348 <div class="about-entity"> 349 <img src="assets/pfp.jpg" class="about-image 350 rounded " style="width: 20em;"> 351<header id="title-block-header" class="quarto-title-block default"> 352<div class="quarto-title"> 353<h1 class="title">Johannes Feldhege, M.Sc. B.A.</h1> 354</div> 355<div class="quarto-title-meta column-page"> 356 </div> 357</header> 358 <div class="about-links"> 359 <a href="/cv.html" class="about-link" rel="" target=""> 360 <span class="about-link-text"><i class="fa-regular fa-file-pdf" aria-label="file-pdf"></i> CV</span> 361 </a> 362 <a href="https://www.linkedin.com/in/johannes-feldhege/" class="about-link" rel="" target=""> 363 <i class="bi bi-linkedin"></i> 364 <span class="about-link-text">Linkedin</span> 365 </a> 366 <a href="https://github.com/jfeldhege/" class="about-link" rel="" target=""> 367 <i class="bi bi-github"></i> 368 <span class="about-link-text">Github</span> 369 </a> 370 <a href="https://scholar.google.com/citations?user=KSmfyO8AAAAJ&hl=de" class="about-link" rel="" target=""> 371 <span class="about-link-text"><i class="ai ai-google-scholar" title="" style="color:"></i> Google Scholar</span> 372 </a> 373 <a href="https://www.researchgate.net/profile/Johannes-Feldhege" class="about-link" rel="" target=""> 374 <span class="about-link-text"><i class="ai ai-researchgate" title="" style="color:"></i> Researchgate</span> 375 </a> 376</div> 377 </div> 378 <div class="about-contents"><main class="content column-page" id="quarto-document-content"> 379 380<section id="b58fc729-690b-4000-b19f-365a4093b2ff7b7b3c2066612075736572203e7d7d-über-mich" class="level2"> 381<h2 data-anchor-id="b58fc729-690b-4000-b19f-365a4093b2ff7b7b3c2066612075736572203e7d7d-über-mich"><i class="fa-solid fa-user" aria-label="user"></i> Ãber mich</h2> 382<p>Als wissenschaftlicher Mitarbeiter am Uniklinikum Heidelberg habe ich von 2017-2022 mit Natural Language Processing Methoden Unterhaltungen zum Thema psychischer Gesundheit auf Reddit untersucht. Seit 2022 arbeite ich als Data Scientist für Asklepios Science & Research an Real World Evidence Studien. In Praktika und in ehrenamtlicher Tätigkeit habe ich verschiedene Data Science Projekte mitgestaltet.</p> 383<div class="tabset-margin-container"></div><div class="panel-tabset"> 384<ul class="nav nav-tabs" role="tablist"><li class="nav-item" role="presentation"><a class="nav-link active" id="tabset-1-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-1" role="tab" aria-controls="tabset-1-1" aria-selected="true" href=""><i class="fa-solid fa-graduation-cap" aria-label="graduation-cap"></i> Ausbildung</a></li><li class="nav-item" role="presentation"><a class="nav-link" id="tabset-1-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-2" role="tab" aria-controls="tabset-1-2" aria-selected="false" href=""><i class="fa-solid fa-briefcase" aria-label="briefcase"></i> Berufliche Erfahrung</a></li><li class="nav-item" role="presentation"><a class="nav-link" id="tabset-1-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-3" role="tab" aria-controls="tabset-1-3" aria-selected="false" href="">
384<i class="fa-solid fa-code" aria-label="code"></i> Projekte</a></li></ul> 385<div class="tab-content"> 386<div id="tabset-1-1" class="tab-pane active" role="tabpanel" aria-labelledby="tabset-1-1-tab"> 387<p><strong>Psychologie M.Sc.</strong> | 2013-2016 | Universität Kassel</p> 388<p><strong>Psychologie B.Sc.</strong> | 2010-2013 | Universität Hamburg</p> 389<p><strong>Soziologie und Sinologie B.A.</strong> | 2007-2010 | Albert-Ludwigs-Universität Freiburg</p> 390<p><strong>International Baccalaureate</strong> | 2007 | Malvern College, United Kingdom</p> 391</div> 392<div id="tabset-1-2" class="tab-pane" role="tabpanel" aria-labelledby="tabset-1-2-tab"> 393<p><strong>Data Scientist</strong> | Asklepios Science & Research, Hamburg | 09/2022-</p> 394<p><strong>Wissenschaftlicher Mitarbeiter</strong> | Forschungsstelle für Psychotherapie, Uniklinikum Heidelberg | 2016-2022</p> 395<p><strong>Data Science Praktikant</strong> | Eoda GmbH, Kassel | 2016</p> 396<p><strong>R Tutor</strong> | Universität Kassel | 2014-2015</p> 397<p><strong>Studentische Hilfskraft</strong> | Servicestelle Empirische Forschungsmethoden, Universität Hamburg | 2011â2013</p> 398</div> 399<div id="tabset-1-3" class="tab-pane" role="tabpanel" aria-labelledby="tabset-1-3-tab"> 400<p><strong>redditoR</strong>: Ein R Paket für Zugriffe auf die API des sozialen Netzwerks Reddit. <a href="https://github.com/jfeldhege/redditoR">Github</a></p> 401<p><strong>Textanalyse von Call-Dokumentationen zur Erarbeitung von Herausforderungen und Erfolgen in vergangenen Projekten</strong>: Ein Projekt mit projecttogether und CorrelAid.</p> 402<p><strong>Die Platte unter der Lupe: Einflussfaktoren auf die Absatzzahlen einer Mannheimer Suppenküche</strong>: Untersuchung der Absatzzahlen des Lokals Mannheimer Platte und deren saisonale und externe Einflussfaktoren. Ein Projekt mit der Mannheimer Platte und CorrelAid. <a href="http://dx.doi.org/10.31219/osf.io/3zsn6">Projektbericht</a></p> 403<p><strong>Experimente mit Quarto Dashboards, WebR und Shinylive</strong>: <a href="https://www.johannesfeldhege.de/dashboard_lifeexp/">Quarto Dashboard</a>, <a href="http://www.johannesfeldhege.de/webr_test/">WebR Testseite</a>, <a href="http://www.johannesfeldhege.de/shinylive_test/">Shinylive in einem Quarto Dokument</a> und <a href="http://www.johannesfeldhege.de/shinylive_test2/">Eine standalone Shinylive App</a></p> 404<p><strong>openholidaysR</strong>: Ein R Paket für Zugriffe auf die OpenHolidays API, die Datumsangaben für Schul- und Feiertage für eine Reihe von Ländern bereitstellt. Jetzt auch auf Cran: <a href="https://cran.r-project.org/web/packages/openholidaysR/index.html">Link zu Cran</a></p> 405</div> 406</div> 407</div> 408<section id="kontakt" class="level4"> 409<h4 data-anchor-id="kontakt">Kontakt:</h4> 410<p><i class="fa-regular fa-envelope" aria-label="envelope"></i> mail [at] johannesfeldhege.de</p> 411 412 413</section> 414</section> 415</main></div> 416</div> 417 <!-- /main -->
418<script id="quarto-html-after-body" type="application/javascript"> 419 window.document.addEventListener("DOMContentLoaded", function (event) { 420 // Ensure there is a toggle, if there isn't float one in the top right 421 if (window.document.querySelector('.quarto-color-scheme-toggle') === null) { 422 const a = window.document.createElement('a'); 423 a.classList.add('top-right'); 424 a.classList.add('quarto-color-scheme-toggle'); 425 a.href = ""; 426 a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; }; 427 const i = window.document.createElement("i"); 428 i.classList.add('bi'); 429 a.appendChild(i); 430 window.document.body.appendChild(a); 431 } 432 setColorSchemeToggle(hasAlternateSentinel()) 433 const isCodeAnnotation = (el) => { 434 for (const clz of el.classList) { 435 if (clz.startsWith('code-annotation-')) { 436 return true; 437 } 438 } 439 return false; 440 } 441 const onCopySuccess = function(e) { 442 // button target 443 const button = e.trigger; 444 // don't keep focus 445 button.blur(); 446 // flash "checked" 447 button.classList.add('code-copy-button-checked'); 448 var currentTitle = button.getAttribute("title"); 449 button.setAttribute("title", "Copied!"); 450 let tooltip; 451 if (window.bootstrap) { 452 button.setAttribute("data-bs-toggle", "tooltip"); 453 button.setAttribute("data-bs-placement", "left"); 454 button.setAttribute("data-bs-title", "Copied!"); 455 tooltip = new bootstrap.Tooltip(button, 456 { trigger: "manual", 457 customClass: "code-copy-button-tooltip", 458 offset: [0, -8]}); 459 tooltip.show(); 460 } 461 setTimeout(function() { 462 if (tooltip) { 463 tooltip.hide(); 464 button.removeAttribute("data-bs-title"); 465 button.removeAttribute("data-bs-toggle"); 466 button.removeAttribute("data-bs-placement"); 467 } 468 button.setAttribute("title", currentTitle); 469 button.classList.remove('code-copy-button-checked'); 470 }, 1000); 471 // clear code selection 472 e.clearSelection(); 473 } 474 const getTextToCopy = function(trigger) { 475 const outerScaffold = trigger.parentElement.cloneNode(true); 476 const codeEl = outerScaffold.querySelector('code'); 477 for (const childEl of codeEl.children) { 478 if (isCodeAnnotation(childEl)) { 479 childEl.remove(); 480 } 481 } 482 return codeEl.innerText; 483 } 484 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 485 text: getTextToCopy 486 }); 487 clipboard.on('success', onCopySuccess); 488 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 489 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 490 text: getTextToCopy, 491 container: window.document.getElementById('quarto-embedded-source-code-modal') 492 }); 493 clipboardModal.on('success', onCopySuccess); 494 } 495 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 496 var mailtoRegex = new RegExp(/^mailto:/); 497 var filterRegex = new RegExp("^(?:http:|https:)\/\/www\.johannesfeldhege\.de\/custom"); 498 var isInternal = (href) => { 499 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 500 } 501 // Inspect non-navigation links and adorn them if external 502 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)'); 503 for (var i=0; i<links.length; i++) { 504 const link = links[i]; 505 if (!isInternal(link.href)) { 506 // undo the damage that might have been done by quarto-nav.js in the case of 507 // links that we want to consider external 508 if (link.dataset.originalHref !== undefined) { 509 link.href = link.dataset.originalHref; 510 } 511 // target, if specified 512 link.setAttribute("target", "_blank"); 513 if (link.getAttribute("rel") === null) { 514 link.setAttribute("rel", "noopener"); 515 } 516 } 517 } 518 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 519 const config = { 520 allowHTML: true, 521 maxWidth: 500, 522 delay: 100,
523 arrow: false, 524 appendTo: function(el) { 525 return el.parentElement; 526 }, 527 interactive: true, 528 interactiveBorder: 10, 529 theme: 'quarto', 530 placement: 'bottom-start', 531 }; 532 if (contentFn) { 533 config.content = contentFn; 534 } 535 if (onTriggerFn) { 536 config.onTrigger = onTriggerFn; 537 } 538 if (onUntriggerFn) { 539 config.onUntrigger = onUntriggerFn; 540 } 541 window.tippy(el, config); 542 } 543 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 544 for (var i=0; i<noterefs.length; i++) { 545 const ref = noterefs[i]; 546 tippyHover(ref, function() { 547 // use id or data attribute instead here 548 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 549 try { href = new URL(href).hash; } catch {} 550 const id = href.replace(/^#\/?/, ""); 551 const note = window.document.getElementById(id); 552 if (note) { 553 return note.innerHTML; 554 } else { 555 return ""; 556 } 557 }); 558 } 559 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 560 const processXRef = (id, note) => { 561 // Strip column container classes 562 const stripColumnClz = (el) => { 563 el.classList.remove("page-full", "page-columns"); 564 if (el.children) { 565 for (const child of el.children) { 566 stripColumnClz(child); 567 } 568 } 569 } 570 stripColumnClz(note) 571 if (id === null || id.startsWith('sec-')) { 572 // Special case sections, only their first couple elements 573 const container = document.createElement("div"); 574 if (note.children && note.children.length > 2) { 575 container.appendChild(note.children[0].cloneNode(true)); 576 for (let i = 1; i < note.children.length; i++) { 577 const child = note.children[i]; 578 if (child.tagName === "P" && child.innerText === "") { 579 continue; 580 } else { 581 container.appendChild(child.cloneNode(true)); 582 break; 583 } 584 } 585 if (window.Quarto?.typesetMath) { 586 window.Quarto.typesetMath(container); 587 } 588 return container.innerHTML 589 } else { 590 if (window.Quarto?.typesetMath) { 591 window.Quarto.typesetMath(note); 592 } 593 return note.innerHTML; 594 } 595 } else { 596 // Remove any anchor links if they are present 597 const anchorLink = note.querySelector('a.anchorjs-link'); 598 if (anchorLink) { 599 anchorLink.remove(); 600 } 601 if (window.Quarto?.typesetMath) { 602 window.Quarto.typesetMath(note); 603 } 604 if (note.classList.contains("callout")) { 605 return note.outerHTML; 606 } else { 607 return note.innerHTML; 608 } 609 } 610 } 611 for (var i=0; i<xrefs.length; i++) { 612 const xref = xrefs[i]; 613 tippyHover(xref, undefined, function(instance) { 614 instance.disable(); 615 let url = xref.getAttribute('href'); 616 let hash = undefined; 617 if (url.startsWith('#')) { 618 hash = url; 619 } else { 620 try { hash = new URL(url).hash; } catch {} 621 } 622 if (hash) { 623 const id = hash.replace(/^#\/?/, ""); 624 const note = window.document.getElementById(id); 625 if (note !== null) { 626 try { 627 const html = processXRef(id, note.cloneNode(true)); 628 instance.setContent(html); 629 } finally { 630 instance.enable(); 631 instance.show(); 632 } 633 } else { 634 // See if we can fetch this 635 fetch(url.split('#')[0]) 636 .then(res => res.text()) 637 .then(html => { 638 const parser = new DOMParser(); 639 const htmlDoc = parser.parseFromString(html, "text/html"); 640 const note = htmlDoc.getElementById(id); 641 if (note !== null) { 642 const html = processXRef(id, note); 643 instance.setContent(html); 644 } 645 }).finally(() => { 646 instance.enable(); 647 instance.show(); 648 }); 649 } 650 } else { 651 // See if we can fetch a full url (with no hash to target)
652 // This is a special case and we should probably do some content thinning / targeting 653 fetch(url) 654 .then(res => res.text()) 655 .then(html => { 656 const parser = new DOMParser(); 657 const htmlDoc = parser.parseFromString(html, "text/html"); 658 const note = htmlDoc.querySelector('main.content'); 659 if (note !== null) { 660 // This should only happen for chapter cross references 661 // (since there is no id in the URL) 662 // remove the first header 663 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 664 note.children[0].remove(); 665 } 666 const html = processXRef(null, note); 667 instance.setContent(html); 668 } 669 }).finally(() => { 670 instance.enable(); 671 instance.show(); 672 }); 673 } 674 }, function(instance) { 675 }); 676 } 677 let selectedAnnoteEl; 678 const selectorForAnnotation = ( cell, annotation) => { 679 let cellAttr = 'data-code-cell="' + cell + '"'; 680 let lineAttr = 'data-code-annotation="' + annotation + '"'; 681 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 682 return selector; 683 } 684 const selectCodeLines = (annoteEl) => { 685 const doc = window.document; 686 const targetCell = annoteEl.getAttribute("data-target-cell"); 687 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 688 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 689 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 690 const lineIds = lines.map((line) => { 691 return targetCell + "-" + line; 692 }) 693 let top = null; 694 let height = null; 695 let parent = null; 696 if (lineIds.length > 0) { 697 //compute the position of the single el (top and bottom and make a div) 698 const el = window.document.getElementById(lineIds[0]); 699 top = el.offsetTop; 700 height = el.offsetHeight; 701 parent = el.parentElement.parentElement; 702 if (lineIds.length > 1) { 703 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 704 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 705 height = bottom - top; 706 } 707 if (top !== null && height !== null && parent !== null) { 708 // cook up a div (if necessary) and position it 709 let div = window.document.getElementById("code-annotation-line-highlight"); 710 if (div === null) { 711 div = window.document.createElement("div"); 712 div.setAttribute("id", "code-annotation-line-highlight"); 713 div.style.position = 'absolute'; 714 parent.appendChild(div); 715 } 716 div.style.top = top - 2 + "px"; 717 div.style.height = height + 4 + "px"; 718 div.style.left = 0; 719 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 720 if (gutterDiv === null) { 721 gutterDiv = window.document.createElement("div"); 722 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 723 gutterDiv.style.position = 'absolute'; 724 const codeCell = window.document.getElementById(targetCell); 725 const gutter = codeCell.querySelector('.code-annotation-gutter'); 726 gutter.appendChild(gutterDiv); 727 } 728 gutterDiv.style.top = top - 2 + "px"; 729 gutterDiv.style.height = height + 4 + "px"; 730 } 731 selectedAnnoteEl = annoteEl; 732 } 733 }; 734 const unselectCodeLines = () => { 735 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 736 elementsIds.forEach((elId) => { 737 const div = window.document.getElementById(elId); 738 if (div) { 739 div.remove(); 740 } 741 }); 742 selectedAnnoteEl = undefined; 743 }; 744 // Handle positioning of the toggle 745 window.addEventListener( 746 "resize", 747 throttle(() => { 748 elRect = undefined; 749 if (selectedAnnoteEl) { 750 selectCodeLines(selectedAnnoteEl); 751 } 752 }, 10) 753 ); 754 function throttle(fn, ms) { 755 let throttle = false;
756 let timer; 757 return (...args) => { 758 if(!throttle) { // first call gets through 759 fn.apply(this, args); 760 throttle = true; 761 } else { // all the others get throttled 762 if(timer) clearTimeout(timer); // cancel #2 763 timer = setTimeout(() => { 764 fn.apply(this, args); 765 timer = throttle = false; 766 }, ms); 767 } 768 }; 769 } 770 // Attach click handler to the DT 771 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 772 for (const annoteDlNode of annoteDls) { 773 annoteDlNode.addEventListener('click', (event) => { 774 const clickedEl = event.target; 775 if (clickedEl !== selectedAnnoteEl) { 776 unselectCodeLines(); 777 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 778 if (activeEl) { 779 activeEl.classList.remove('code-annotation-active'); 780 } 781 selectCodeLines(clickedEl); 782 clickedEl.classList.add('code-annotation-active'); 783 } else { 784 // Unselect the line 785 unselectCodeLines(); 786 clickedEl.classList.remove('code-annotation-active'); 787 } 788 }); 789 } 790 const findCites = (el) => { 791 const parentEl = el.parentElement; 792 if (parentEl) { 793 const cites = parentEl.dataset.cites; 794 if (cites) { 795 return { 796 el, 797 cites: cites.split(' ') 798 }; 799 } else { 800 return findCites(el.parentElement) 801 } 802 } else { 803 return undefined; 804 } 805 }; 806 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 807 for (var i=0; i<bibliorefs.length; i++) { 808 const ref = bibliorefs[i]; 809 const citeInfo = findCites(ref); 810 if (citeInfo) { 811 tippyHover(citeInfo.el, function() { 812 var popup = window.document.createElement('div'); 813 citeInfo.cites.forEach(function(cite) { 814 var citeDiv = window.document.createElement('div'); 815 citeDiv.classList.add('hanging-indent'); 816 citeDiv.classList.add('csl-entry'); 817 var biblioDiv = window.document.getElementById('ref-' + cite); 818 if (biblioDiv) { 819 citeDiv.innerHTML = biblioDiv.innerHTML; 820 } 821 popup.appendChild(citeDiv); 822 }); 823 return popup.innerHTML; 824 }); 825 } 826 } 827 }); 828 </script>
828 829</div> <!-- /content --> 830<footer class="footer"> 831 <div class="nav-footer"> 832 <div class="nav-footer-left"> 833 834 </div> 835 <div class="nav-footer-center"> 836 837<div class="cookie-consent-footer"><a href="#" id="open_preferences_center">Cookie Preferences</a></div></div> 838 <div class="nav-footer-right"> 839<p>Mit <i class="fa-brands fa-r-project" aria-label="r-project"></i> und <a href="https://quarto.org/">Quarto</a> erstellt.<br> Source Code auf <a href="https://github.com/jfeldhege/jfeldhege.github.io"><i class="fa-brands fa-github" aria-label="github"></i> GitHub</a></p> 840</div> 841 </div> 842</footer> 843 844 845 846 847</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.