First blog post, added theming
All checks were successful
Build blog / build (push) Successful in 1s
All checks were successful
Build blog / build (push) Successful in 1s
Coffee-themed, font changes and a first post.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@ public/
|
||||
out/
|
||||
__pycache__/
|
||||
*/template.md
|
||||
.crossnote/
|
||||
WIP
|
||||
8
build.py
8
build.py
@@ -64,7 +64,13 @@ def parse(path):
|
||||
"date": when,
|
||||
"topic": rel.parts[0] if len(rel.parts) > 1 else meta.get("topic"),
|
||||
"slug": slugify(meta.get("slug") or re.sub(r"^\d{4}-\d{2}-\d{2}-", "", path.stem)),
|
||||
"body": markdown.markdown(text, extensions=["fenced_code", "tables", "footnotes"]),
|
||||
"body": markdown.markdown(
|
||||
text,
|
||||
extensions=[
|
||||
"fenced_code", "tables", "footnotes", "codehilite", "abbr",
|
||||
],
|
||||
extension_configs={"codehilite": {"guess_lang": False}},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
|
||||
93
static/OFL.txt
Normal file
93
static/OFL.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The Poltawski Nowy Project Authors (https://github.com/kosmynkab/Poltawski-Nowy)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
static/PoltawskiNowy-Bold.ttf
Normal file
BIN
static/PoltawskiNowy-Bold.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-BoldItalic.ttf
Normal file
BIN
static/PoltawskiNowy-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-Italic-VariableFont_wght.ttf
Normal file
BIN
static/PoltawskiNowy-Italic-VariableFont_wght.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-Italic.ttf
Normal file
BIN
static/PoltawskiNowy-Italic.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-Medium.ttf
Normal file
BIN
static/PoltawskiNowy-Medium.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-MediumItalic.ttf
Normal file
BIN
static/PoltawskiNowy-MediumItalic.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-Regular.ttf
Normal file
BIN
static/PoltawskiNowy-Regular.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-SemiBold.ttf
Normal file
BIN
static/PoltawskiNowy-SemiBold.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-SemiBoldItalic.ttf
Normal file
BIN
static/PoltawskiNowy-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
static/PoltawskiNowy-VariableFont_wght.ttf
Normal file
BIN
static/PoltawskiNowy-VariableFont_wght.ttf
Normal file
Binary file not shown.
222
template.html
222
template.html
@@ -4,48 +4,158 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Pascal Maas · Blog</title>
|
||||
<script>
|
||||
// Runs before the page is drawn, so a saved dark choice doesn't flash.
|
||||
try {
|
||||
if (localStorage.getItem("theme") === "dark") {
|
||||
document.documentElement.dataset.theme = "dark";
|
||||
}
|
||||
} catch (error) {}
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #fbfaf7; --fg: #1d1d1b; --muted: #6b6a66; --line: #e4e1da;
|
||||
--accent: #2f5d8a; --code-bg: #f1eee7;
|
||||
/* Served from static/; Georgia shows until these have loaded. */
|
||||
@font-face {
|
||||
font-family: "Poltawski Nowy"; font-weight: 400; font-style: normal;
|
||||
src: url("static/PoltawskiNowy-Regular.ttf"); font-display: swap;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #161616; --fg: #e8e6e1; --muted: #9a978f; --line: #2c2b29;
|
||||
--accent: #8ab4dc; --code-bg: #222120;
|
||||
@font-face {
|
||||
font-family: "Poltawski Nowy"; font-weight: 400; font-style: italic;
|
||||
src: url("static/PoltawskiNowy-Italic.ttf"); font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Poltawski Nowy"; font-weight: 700; font-style: normal;
|
||||
src: url("static/PoltawskiNowy-Bold.ttf"); font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Poltawski Nowy"; font-weight: 700; font-style: italic;
|
||||
src: url("static/PoltawskiNowy-BoldItalic.ttf"); font-display: swap;
|
||||
}
|
||||
:root {
|
||||
--latte: #f4f2ee; --espresso: #231c15;
|
||||
--espresso-button: #4a3326; --latte-button: #e3d9cb;
|
||||
--bg: var(--latte); --fg: #1d1d1b; --muted: #6b6a66; --line: #dbd6cc;
|
||||
--accent: #2f5d8a; --code-bg: #eae6e0;
|
||||
/* Pinned header; the side list pins just below it. */
|
||||
--header-height: 3.25rem; --header-bg: #ebe8e1;
|
||||
--code-block-bg: #eae6e0; --code-text: #1d1d1b;
|
||||
--code-comment: #7a7a7a; --code-keyword: #a85a1e; --code-string: #4f6b3f;
|
||||
--code-number: #4a6f8f; --code-function: #8a6500;
|
||||
}
|
||||
:root[data-theme="dark"] {
|
||||
--bg: var(--espresso); --fg: #e8e6e1; --muted: #9a978f; --line: #3d3227;
|
||||
--accent: #8ab4dc; --code-bg: #2f261d; --header-bg: #2c231a;
|
||||
--code-block-bg: #2e2822; --code-text: #d6d4cf;
|
||||
--code-comment: #808080; --code-keyword: #cc7832; --code-string: #6a8759;
|
||||
--code-number: #6897bb; --code-function: #ffc66d;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0; background: var(--bg); color: var(--fg);
|
||||
font: 17px/1.65 Georgia, "Iowan Old Style", "Times New Roman", serif;
|
||||
font: 17px/1.65 "Poltawski Nowy", Georgia, "Iowan Old Style",
|
||||
"Times New Roman", serif;
|
||||
}
|
||||
.wrap { max-width: 44rem; margin: 0 auto; padding: 3rem 1rem 4rem; }
|
||||
.wrap { max-width: 56rem; margin: 0 auto; padding: 0 1rem 4rem; }
|
||||
a { color: var(--accent); }
|
||||
h1, h2, h3, .meta, nav, footer { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; }
|
||||
.site-header h1 { margin: 0; font-size: 1.6rem; letter-spacing: -0.01em; }
|
||||
.site-header p { margin: .25rem 0 0; color: var(--muted); }
|
||||
.site-header h1 {
|
||||
margin: 0; font-size: 1.6rem; line-height: 1.2; letter-spacing: -0.01em;
|
||||
}
|
||||
.site-header p { display: none; margin: 0; color: var(--muted); }
|
||||
.site-header {
|
||||
display: flex; justify-content: space-between;
|
||||
align-items: center; gap: 1rem;
|
||||
position: sticky; top: 0; z-index: 2; background: var(--header-bg);
|
||||
height: var(--header-height); padding: .5rem 0;
|
||||
/* Stretches the colour and the line under it to the full window width
|
||||
while the contents stay in the column. */
|
||||
box-shadow: 0 0 0 100vmax var(--header-bg), 0 1px 0 100vmax var(--line);
|
||||
clip-path: inset(0 -100vmax -1px);
|
||||
}
|
||||
.header-actions { display: flex; align-items: center; gap: .75rem; }
|
||||
.site-header p, .header-actions { font-size: 15px; }
|
||||
/* Same font as the tagline; buttons don't inherit it by default. */
|
||||
.header-actions a, .theme-toggle { font: inherit; }
|
||||
.header-actions a { color: var(--fg); text-decoration: none; }
|
||||
.header-actions a:hover { text-decoration: underline; }
|
||||
/* Espresso brown in light mode, latte beige in dark mode. */
|
||||
.theme-toggle {
|
||||
color: var(--latte); background: var(--espresso-button); cursor: pointer;
|
||||
border: 1px solid var(--espresso-button); border-radius: 999px;
|
||||
/* Fixed width fits "Espresso", so the Git link doesn't shift. */
|
||||
width: 6em; padding: .2rem 0; text-align: center;
|
||||
}
|
||||
:root[data-theme="dark"] .theme-toggle {
|
||||
color: var(--espresso); background: var(--latte-button);
|
||||
border-color: var(--latte-button);
|
||||
}
|
||||
.theme-toggle:hover { opacity: .85; }
|
||||
/* Wide enough for the tagline next to the name; hidden below this. */
|
||||
@media (min-width: 52rem) {
|
||||
.site-title { display: flex; align-items: baseline; gap: .75rem; }
|
||||
.site-header p { display: block; }
|
||||
}
|
||||
|
||||
nav { margin: 2.5rem 0 1rem; padding: 1rem 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
|
||||
nav { margin: 2.5rem 0 1rem; padding: 1rem 0; border-bottom: 1px solid var(--line); }
|
||||
nav h2 { margin: 0 0 .5rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
|
||||
nav ol { margin: 0; padding: 0; list-style: none; }
|
||||
nav li { display: flex; justify-content: space-between; gap: 1rem; padding: .2rem 0; }
|
||||
nav li time { color: var(--muted); font-size: .85rem; white-space: nowrap; }
|
||||
nav a { text-decoration: none; }
|
||||
nav a:hover { text-decoration: underline; }
|
||||
nav a.current { font-weight: 700; color: var(--fg); }
|
||||
|
||||
/* Side column (14rem) + gap (3rem) + posts (56rem) + padding (2rem). */
|
||||
@media (min-width: 75rem) {
|
||||
.wrap { max-width: 75rem; }
|
||||
.layout { display: grid; grid-template-columns: 14rem 56rem; gap: 3rem; }
|
||||
nav {
|
||||
position: sticky; top: var(--header-height); align-self: start;
|
||||
max-height: calc(100vh - var(--header-height)); overflow-y: auto;
|
||||
margin: 0; padding: 2.5rem 0 1rem; border: none;
|
||||
}
|
||||
nav li, nav li time { display: block; }
|
||||
}
|
||||
|
||||
article { padding: 2.5rem 0; border-bottom: 1px solid var(--line); scroll-margin-top: 1rem; }
|
||||
/* Keeps in-page jumps (footnotes) clear of the pinned header. */
|
||||
html { scroll-padding-top: calc(var(--header-height) + 1rem); }
|
||||
article header h2 { margin: 0; font-size: 1.45rem; line-height: 1.25; }
|
||||
article header h2 a { color: inherit; text-decoration: none; }
|
||||
article header h2 a:hover { color: var(--accent); }
|
||||
.meta { margin: .35rem 0 1.25rem; font-size: .85rem; color: var(--muted); display: flex; gap: .75rem; align-items: center; }
|
||||
.tag { border: 1px solid var(--line); border-radius: 999px; padding: 0 .55rem; }
|
||||
|
||||
img { max-width: 100%; height: auto; }
|
||||
/* Defined terms (Markdown "*[term]: definition"); the script below fills
|
||||
data-definition with the text for the bubble. */
|
||||
abbr[data-definition] {
|
||||
position: relative; cursor: help;
|
||||
text-decoration: underline dotted; text-underline-offset: .2em;
|
||||
}
|
||||
abbr[data-definition]:is(:hover, :focus)::after {
|
||||
content: attr(data-definition);
|
||||
position: absolute; left: 50%; bottom: 100%; z-index: 3;
|
||||
transform: translateX(-50%); margin-bottom: .35rem;
|
||||
width: max-content; max-width: 16rem; padding: .35rem .6rem;
|
||||
background: var(--header-bg); color: var(--fg);
|
||||
border: 1px solid var(--line); border-radius: 6px;
|
||||
font-size: .85rem; line-height: 1.4;
|
||||
}
|
||||
|
||||
img { display: block; margin: 0 auto; max-width: 100%; height: auto; }
|
||||
pre, code { font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace; font-size: .88em; }
|
||||
code { background: var(--code-bg); padding: .1em .3em; border-radius: 4px; }
|
||||
pre { background: var(--code-bg); padding: 1rem; border-radius: 6px; overflow-x: auto; }
|
||||
pre { background: var(--code-block-bg); color: var(--code-text); padding: 1rem; border-radius: 6px; overflow-x: auto; }
|
||||
pre code { background: none; padding: 0; }
|
||||
/* Pygments token classes, Darcula colours: comments, keywords, strings,
|
||||
numbers, function names. */
|
||||
.codehilite :is(.c, .c1, .cm, .ch, .cs) {
|
||||
color: var(--code-comment); font-style: italic;
|
||||
}
|
||||
.codehilite :is(.k, .kc, .kd, .kn, .kr, .kt) { color: var(--code-keyword); }
|
||||
.codehilite :is(.s, .s1, .s2, .sa, .sd, .se, .si) {
|
||||
color: var(--code-string);
|
||||
}
|
||||
.codehilite :is(.m, .mi, .mf, .mh, .il) { color: var(--code-number); }
|
||||
.codehilite :is(.nf, .nb, .fm) { color: var(--code-function); }
|
||||
blockquote { margin: 1.25rem 0; padding-left: 1rem; border-left: 3px solid var(--line); color: var(--muted); }
|
||||
table { border-collapse: collapse; width: 100%; display: block; overflow-x: auto; }
|
||||
th, td { border: 1px solid var(--line); padding: .4rem .6rem; text-align: left; }
|
||||
@@ -56,10 +166,20 @@
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<header class="site-header">
|
||||
<div class="site-title">
|
||||
<h1>Pascal Maas</h1>
|
||||
<p>Notes and writing.</p>
|
||||
<p>A blog about bioinformatics in metabolomics</p>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<a href="https://git.pascal-maas.nl/pascalmaas" target="_blank"
|
||||
rel="me noopener">Git</a>
|
||||
<a href="mailto:contact@pascal-maas.nl">Contact</a>
|
||||
<button class="theme-toggle" type="button"
|
||||
title="Switch to dark mode">Espresso</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="layout">
|
||||
<nav aria-label="Posts">
|
||||
<h2>Posts</h2>
|
||||
<ol>
|
||||
@@ -70,8 +190,78 @@
|
||||
<main>
|
||||
{{posts}}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer>© {{year}} Pascal Maas</footer>
|
||||
</div>
|
||||
<script>
|
||||
const root = document.documentElement;
|
||||
const button = document.querySelector(".theme-toggle");
|
||||
|
||||
// The button names the mode it switches to, not the current one.
|
||||
function applyTheme(theme) {
|
||||
root.dataset.theme = theme;
|
||||
if (theme === "dark") {
|
||||
button.textContent = "Latte";
|
||||
button.title = "Switch to light mode";
|
||||
} else {
|
||||
button.textContent = "Espresso";
|
||||
button.title = "Switch to dark mode";
|
||||
}
|
||||
}
|
||||
|
||||
applyTheme(root.dataset.theme || "light");
|
||||
button.addEventListener("click", function () {
|
||||
const theme = root.dataset.theme === "dark" ? "light" : "dark";
|
||||
applyTheme(theme);
|
||||
try {
|
||||
localStorage.setItem("theme", theme);
|
||||
} catch (error) {}
|
||||
});
|
||||
|
||||
const header = document.querySelector(".site-header");
|
||||
const articles = Array.from(document.querySelectorAll("main article"));
|
||||
const links = document.querySelectorAll("nav a");
|
||||
|
||||
// First use of each term per post keeps its definition, moved out of
|
||||
// "title" so the browser's plain tooltip doesn't show beside the bubble.
|
||||
for (const article of articles) {
|
||||
const seen = new Set();
|
||||
for (const term of article.querySelectorAll("abbr[title]")) {
|
||||
if (seen.has(term.textContent)) {
|
||||
term.replaceWith(term.textContent);
|
||||
continue;
|
||||
}
|
||||
seen.add(term.textContent);
|
||||
term.dataset.definition = term.title;
|
||||
term.removeAttribute("title");
|
||||
term.tabIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// The current post is the last one whose top has passed a line 3rem
|
||||
// (48px) below the header; at the very bottom, it is always the last post.
|
||||
function markCurrentPost() {
|
||||
if (articles.length === 0) {
|
||||
return;
|
||||
}
|
||||
const line = header.getBoundingClientRect().bottom + 48;
|
||||
const viewBottom = window.innerHeight + window.scrollY;
|
||||
const atBottom = viewBottom >= root.scrollHeight - 2;
|
||||
let current = articles[0];
|
||||
for (const article of articles) {
|
||||
if (atBottom || article.getBoundingClientRect().top <= line) {
|
||||
current = article;
|
||||
}
|
||||
}
|
||||
for (const link of links) {
|
||||
link.classList.toggle("current", link.hash === "#" + current.id);
|
||||
}
|
||||
}
|
||||
|
||||
markCurrentPost();
|
||||
window.addEventListener("scroll", markCurrentPost, { passive: true });
|
||||
window.addEventListener("resize", markCurrentPost);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
16
topics/starting-a-blog.md
Normal file
16
topics/starting-a-blog.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: Starting a blog
|
||||
date: 2026-10-04
|
||||
---
|
||||
|
||||
Hi there! This is my first post in hopefully many. I'm Pascal and work as a bioinformatician in the field of metabolomics. I studied bioinformatics, getting my master degree in 2020 at the University of Amsterdam and since then I work at the Metabolomics Analytical Centre, which is part of the University of Leiden. Here I develop software to support the data analysis of large volumes of samples. This however, remains a challenge for reasons that hopefully become clear through posts on this blog. Ofcourse, I will also attempt to provide solutions for practical challenges I've encounted.
|
||||
|
||||
I decided to start this blog to share my experience with data analysis in metabolomics as publishing articles is a slow process, and might not be the right platform for sharing everyday encounters. I've been enjoying reading other blogs like [yet another metabolomics club](https://metabolomics.blog) & [Notes from a data witch](https://blog.djnavarro.net), and it seemed the right fit to share my thoughts, ideas and code snippets. I'll post those to my [git](https://git.pascal-maas.nl/explore/repos). Except to see code mostly written in R, Python and perhaps some C++.
|
||||
|
||||
In the office I'm known for drinking way too much coffee (although I don't see anything wrong with my consumption..). For this reason I called the light/dark mode after coffee drinks and themed the blog as such. I'm genuinely curious how big the caffeine spike would be on our LC-MS systems, but since the assay uses plasma it will remain a mystery to this day. Perhaps DBS based metabolomics would be my best bet..
|
||||
|
||||
Anyways, enjoy your stay!
|
||||
|
||||
|
||||
*[bioinformatics]: An interdisciplinary field of science that develops computational methods and software tools for understanding biological data
|
||||
*[DBS]: Dried Blood Spots, a promising, minimally invasive techninique for blood sampling.
|
||||
Reference in New Issue
Block a user