commit 75562787a225e7c6cb157709e25501972f70bd08 Author: Nathaniel Moll Date: Sun Oct 22 23:51:30 2023 -0400 First commit diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/.hugo_build.lock b/.hugo_build.lock new file mode 100644 index 0000000..e69de29 diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..00e77bd --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..071c893 --- /dev/null +++ b/config.toml @@ -0,0 +1,15 @@ +baseURL = "https://nathan.freedomland.xyz" +languageCode = "en-us" +title = "Blog" +theme = "lekh" + +[params] +Name = "Nathan Moll" +About = "" +Email = "" +Resume = "" # Add the filename with file extension. +PostLimit = 4 # Sets the number of posts to display on the front page + +[[params.profiles]] +name = "Gitea" +url = "https://git.freedomland.xyz/darthmoll12" diff --git a/content/posts/_index.md b/content/posts/_index.md new file mode 100644 index 0000000..f5a4c51 --- /dev/null +++ b/content/posts/_index.md @@ -0,0 +1,5 @@ ++++ +title = "Nathan's Blog Posts" ++++ + +We can add some content diff --git a/content/posts/first.md b/content/posts/first.md new file mode 100644 index 0000000..85c250b --- /dev/null +++ b/content/posts/first.md @@ -0,0 +1,7 @@ +--- +title: "First post ever!!!!" +tags: ["test", "test2"] +categories: ["announcements"] +--- + +This is my first post and it's useless!!! :D :D :D diff --git a/layouts/page/contact.html b/layouts/page/contact.html new file mode 100644 index 0000000..e69de29 diff --git a/layouts/page/single.html b/layouts/page/single.html new file mode 100644 index 0000000..e69de29 diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..fa5af61 --- /dev/null +++ b/public/404.html @@ -0,0 +1,20 @@ + + + + 404 Page Not Found | My New Hugo Site + + + + + + + + + + + +

This page does not exist or as they say, it's a 404 error

+

If you can't find what you're looking for, it's better to sometimes look inside

+ + + \ No newline at end of file diff --git a/public/categories/index.html b/public/categories/index.html new file mode 100644 index 0000000..d3bc51a --- /dev/null +++ b/public/categories/index.html @@ -0,0 +1,43 @@ + + + Categories | My New Hugo Site + + + + + + + + + + + + + + + + + + + + + +

+ Categories +

+ + + + + + + + + + + diff --git a/public/categories/index.xml b/public/categories/index.xml new file mode 100644 index 0000000..b92677a --- /dev/null +++ b/public/categories/index.xml @@ -0,0 +1,10 @@ + + + + Categories on My New Hugo Site + http://example.org/categories/ + Recent content in Categories on My New Hugo Site + Hugo -- gohugo.io + en-us + + diff --git a/public/css/fonts.css b/public/css/fonts.css new file mode 100644 index 0000000..a4b30a4 --- /dev/null +++ b/public/css/fonts.css @@ -0,0 +1,33 @@ +/* Monospace */ +@font-face { + font-family: 'Source Code Pro Light'; + src: url('../assets/fonts/SourceCodePro-Light.otf'); + font-weight: normal; + font-style: normal; +} + +/* Regular */ +@font-face { + font-family: 'Calendas Plus'; + src: url('../assets/fonts/calendas_plus-webfont.eot'); + src: url('../assets/fonts/calendas_plus-webfont.eot?#iefix') format('embedded-opentype'), + url('../assets/fonts/calendas_plus-webfont.woff2') format('woff2'), + url('../assets/fonts/calendas_plus-webfont.woff') format('woff'), + url('../assets/fonts/calendas_plus-webfont.ttf') format('truetype'), + url('../assets/fonts/calendas_plus-webfont.svg#calendas_plusregular') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* Bold */ +@font-face { + font-family: 'Calendas Plus'; + src: url('../assets/fonts/calendas_plus_bold-webfont.eot'); + src: url('../assets/fonts/calendas_plus_bold-webfont.eot?#iefix') format('embedded-opentype'), + url('../assets/fonts/calendas_plus_bold-webfont.woff2') format('woff2'), + url('../assets/fonts/calendas_plus_bold-webfont.woff') format('woff'), + url('../assets/fonts/calendas_plus_bold-webfont.ttf') format('truetype'), + url('../assets/fonts/calendas_plus_bold-webfont.svg#calendas_plusbold') format('svg'); + font-weight: bold; + font-style: normal; +} diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..b6c6a02 --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,57 @@ +body { +font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; +line-height: 1.5em; +font-size: 1.1em; +color: #222; +max-width: 70%; +padding: 2rem; +margin: auto; +background: #fafafa; +overscroll-behavior-y: none; +} + +img { +max-width: 100%; } + +a { +color: #0074D9; } + +h1, h2, strong { +color: #111; } + +h1 { +font-size: 1.6em; } + +h2 { +font-size: 1.2em; } + +h3 { +font-size: 1.1em; } + +.muted { +color: #aaa; +text-decoration: none; } + +.small { +font-size: .8em; } + +hr { +border: 0px; +border: 1px solid #eee; +} + + +highlight { +} + +pre code span span{ +word-break: break-all; +white-space: pre-wrap; +} + + +.taglist { +border: solid; +border-weight: 2pt; +padding: 4pt; +} diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..a7ceae3 --- /dev/null +++ b/public/index.html @@ -0,0 +1,53 @@ + + + + + My New Hugo Site + + + + + + + + + + + + +

+

+ +
+ + + + + + + + + + + + + + + +
 Resume
 
+ +

Posts

+ +
+ + + +
+

View all posts

+

View all categories

+

View all tags

+
+ + + + diff --git a/public/index.xml b/public/index.xml new file mode 100644 index 0000000..19dd81c --- /dev/null +++ b/public/index.xml @@ -0,0 +1,19 @@ + + + + My New Hugo Site + http://example.org/ + Recent content on My New Hugo Site + Hugo -- gohugo.io + en-us + + + http://example.org/contact/ + Mon, 01 Jan 0001 00:00:00 +0000 + + http://example.org/contact/ + layout = &lsquo;contact&rsquo; title = &lsquo;Contact&rsquo; + + + + diff --git a/public/js/dark.js b/public/js/dark.js new file mode 100644 index 0000000..d3ec62f --- /dev/null +++ b/public/js/dark.js @@ -0,0 +1,440 @@ +// darkmode.js: Javascript library for controlling page appearance, toggling between regular white and 'dark mode' +// Author: Said Achmiz +// Date: 2020-03-20 +// When: Time-stamp: "2020-03-23 09:36:20 gwern" +// license: PD +// Author: Judah Sotomayor +// Date: 2023-10-15 +// When: <2023-10-15 Sun 18:37> + +/* For gwern.net, the default white-black */ +/* scheme is 'light', and it can be flipped to a 'dark' scheme fairly easily by inverting it; the main visual problem is */ +/* that blockquotes appear to become much harder to see & image-focus.js doesn't work well without additional tweaks. */ +/* Known bugs: images get inverted on zoom or hover; invert filters are slow, leading to 'janky' slow rendering on scrolling. */ + +/****************/ +/* MISC HELPERS */ +/****************/ + +/* Given an HTML string, creates an element from that HTML, adds it to + #ui-elements-container (creating the latter if it does not exist), and + returns the created element. + */ +function addUIElement(element_html) { + var ui_elements_container = document.getElementById('ui-elements-container'); + if (!ui_elements_container) { + ui_elements_container = document.createElement("div"); + ui_elements_container.id = "ui-elements-container"; + document.querySelector("body").appendChild(ui_elements_container); + } + + ui_elements_container.insertAdjacentHTML("beforeend", element_html); + return ui_elements_container.lastElementChild; +} + +if (typeof window.GW == "undefined") + window.GW = { }; +GW.temp = { }; + +if (GW.mediaQueries == null) + GW.mediaQueries = { }; +GW.mediaQueries.mobileNarrow = matchMedia("(max-width: 520px)"); +GW.mediaQueries.mobileWide = matchMedia("(max-width: 900px)"); +GW.mediaQueries.mobileMax = matchMedia("(max-width: 960px)"); +GW.mediaQueries.hover = matchMedia("only screen and (hover: hover) and (pointer: fine)"); +GW.mediaQueries.systemDarkModeActive = matchMedia("(prefers-color-scheme: dark)"); + +GW.modeOptions = [ + [ 'auto', 'Auto', 'Set light or dark mode automatically, according to system-wide setting' ], + [ 'light', 'Light', 'Light mode at all times' ], + [ 'dark', 'Dark', 'Dark mode at all times' ] +]; +GW.modeStyles = ` + :root { + --GW-blockquote-background-color: #ddd + } + body::before, + body > * { + filter: invert(90%) + } + body::before { + content: ''; + width: 100vw; + height: 100%; + position: fixed; + left: 0; + top: 0; + background-color: #fff; + z-index: -1 + } + img, + video { + filter: invert(100%); + } + #markdownBody, #mode-selector button { + text-shadow: 0 0 0 #000 + } + article > :not(#TOC) a:link { + text-shadow: + 0 0 #777, + .03em 0 #fff, + -.03em 0 #fff, + 0 .03em #fff, + 0 -.03em #fff, + .06em 0 #fff, + -.06em 0 #fff, + .09em 0 #fff, + -.09em 0 #fff, + .12em 0 #fff, + -.12em 0 #fff, + .15em 0 #fff, + -.15em 0 #fff + } + article > :not(#TOC) blockquote a:link { + text-shadow: + 0 0 #777, + .03em 0 var(--GW-blockquote-background-color), + -.03em 0 var(--GW-blockquote-background-color), + 0 .03em var(--GW-blockquote-background-color), + 0 -.03em var(--GW-blockquote-background-color), + .06em 0 var(--GW-blockquote-background-color), + -.06em 0 var(--GW-blockquote-background-color), + .09em 0 var(--GW-blockquote-background-color), + -.09em 0 var(--GW-blockquote-background-color), + .12em 0 var(--GW-blockquote-background-color), + -.12em 0 var(--GW-blockquote-background-color), + .15em 0 var(--GW-blockquote-background-color), + -.15em 0 var(--GW-blockquote-background-color) + } + #logo img { + filter: none; + } + #mode-selector { + opacity: 0.6; + } + #mode-selector:hover { + background-color: #fff; + } +`; + +/****************/ +/* DEBUG OUTPUT */ +/****************/ + +function GWLog (string) { + if (GW.loggingEnabled || localStorage.getItem("logging-enabled") == "true") + console.log(string); +} + +/***********/ +/* HELPERS */ +/***********/ + +/* Run the given function immediately if the page is already loaded, or add + a listener to run it as soon as the page loads. + */ +function doWhenPageLoaded(f) { + if (document.readyState == "complete") + f(); + else + window.addEventListener("load", f); +} + +/* Adds an event listener to a button (or other clickable element), attaching + it to both "click" and "keyup" events (for use with keyboard navigation). + Optionally also attaches the listener to the 'mousedown' event, making the + element activate on mouse down instead of mouse up. + */ +Element.prototype.addActivateEvent = function(func, includeMouseDown) { + let ael = this.activateEventListener = (event) => { if (event.button === 0 || event.key === ' ') func(event) }; + if (includeMouseDown) this.addEventListener("mousedown", ael); + this.addEventListener("click", ael); + this.addEventListener("keyup", ael); +} + +/* Adds a scroll event listener to the page. + */ +function addScrollListener(fn, name) { + let wrapper = (event) => { + requestAnimationFrame(() => { + fn(event); + document.addEventListener("scroll", wrapper, { once: true, passive: true }); + }); + } + document.addEventListener("scroll", wrapper, { once: true, passive: true }); + + // Retain a reference to the scroll listener, if a name is provided. + if (typeof name != "undefined") + GW[name] = wrapper; +} + +/************************/ +/* ACTIVE MEDIA QUERIES */ +/************************/ + +/* This function provides two slightly different versions of its functionality, + depending on how many arguments it gets. + + If one function is given (in addition to the media query and its name), it + is called whenever the media query changes (in either direction). + + If two functions are given (in addition to the media query and its name), + then the first function is called whenever the media query starts matching, + and the second function is called whenever the media query stops matching. + + If you want to call a function for a change in one direction only, pass an + empty closure (NOT null!) as one of the function arguments. + + There is also an optional fifth argument. This should be a function to be + called when the active media query is canceled. + */ +function doWhenMatchMedia(mediaQuery, name, ifMatchesOrAlwaysDo, otherwiseDo = null, whenCanceledDo = null) { + if (typeof GW.mediaQueryResponders == "undefined") + GW.mediaQueryResponders = { }; + + let mediaQueryResponder = (event, canceling = false) => { + if (canceling) { + GWLog(`Canceling media query “${name}”`); + + if (whenCanceledDo != null) + whenCanceledDo(mediaQuery); + } else { + let matches = (typeof event == "undefined") ? mediaQuery.matches : event.matches; + + GWLog(`Media query “${name}” triggered (matches: ${matches ? "YES" : "NO"})`); + + if (otherwiseDo == null || matches) ifMatchesOrAlwaysDo(mediaQuery); + else otherwiseDo(mediaQuery); + } + }; + mediaQueryResponder(); + mediaQuery.addListener(mediaQueryResponder); + + GW.mediaQueryResponders[name] = mediaQueryResponder; +} + +/* Deactivates and discards an active media query, after calling the function + that was passed as the whenCanceledDo parameter when the media query was + added. + */ +function cancelDoWhenMatchMedia(name) { + GW.mediaQueryResponders[name](null, true); + + for ([ key, mediaQuery ] of Object.entries(GW.mediaQueries)) + mediaQuery.removeListener(GW.mediaQueryResponders[name]); + + GW.mediaQueryResponders[name] = null; +} + +/******************/ +/* MODE SELECTION */ +/******************/ + +function injectModeSelector() { + GWLog("injectModeSelector"); + + // Get saved mode setting (or default). + let currentMode = localStorage.getItem("selected-mode") || 'auto'; + + // Inject the mode selector widget and activate buttons. + let modeSelector = addUIElement( + "
" + + String.prototype.concat.apply("", GW.modeOptions.map(modeOption => { + let [ name, label, desc ] = modeOption; + let selected = (name == currentMode ? ' selected' : ''); + let disabled = (name == currentMode ? ' disabled' : ''); + return ``})) + + "
"); + + modeSelector.querySelectorAll("button").forEach(button => { + button.addActivateEvent(GW.modeSelectButtonClicked = (event) => { + GWLog("GW.modeSelectButtonClicked"); + + // Determine which setting was chosen (i.e., which button was clicked). + let selectedMode = event.target.dataset.name; + + // Save the new setting. + if (selectedMode == "auto") localStorage.removeItem("selected-mode"); + else localStorage.setItem("selected-mode", selectedMode); + + // Actually change the mode. + setMode(selectedMode); + }); + }); + + document.querySelector("head").insertAdjacentHTML("beforeend", ``); + + document.querySelector("head").insertAdjacentHTML("beforeend", ``); + + setMode(currentMode); + + // We pre-query the relevant elements, so we don’t have to run queryAll on + // every firing of the scroll listener. + GW.scrollState = { + "lastScrollTop": window.pageYOffset || document.documentElement.scrollTop, + "unbrokenDownScrollDistance": 0, + "unbrokenUpScrollDistance": 0, + "modeSelector": document.querySelectorAll("#mode-selector"), + }; + addScrollListener(updateModeSelectorVisibility, "updateModeSelectorVisibilityScrollListener"); + GW.scrollState.modeSelector[0].addEventListener("mouseover", () => { showModeSelector(); }); + doWhenMatchMedia(GW.mediaQueries.systemDarkModeActive, "updateModeSelectorStateForSystemDarkMode", () => { updateModeSelectorState(); }); +} + +/* Show/hide the mode selector in response to scrolling. + + Called by the ‘updateModeSelectorVisibilityScrollListener’ scroll listener. + */ +function updateModeSelectorVisibility(event) { + GWLog("updateModeSelectorVisibility"); + + let newScrollTop = window.pageYOffset || document.documentElement.scrollTop; + GW.scrollState.unbrokenDownScrollDistance = (newScrollTop > GW.scrollState.lastScrollTop) ? + (GW.scrollState.unbrokenDownScrollDistance + newScrollTop - GW.scrollState.lastScrollTop) : + 0; + GW.scrollState.unbrokenUpScrollDistance = (newScrollTop < GW.scrollState.lastScrollTop) ? + (GW.scrollState.unbrokenUpScrollDistance + GW.scrollState.lastScrollTop - newScrollTop) : + 0; + GW.scrollState.lastScrollTop = newScrollTop; + + // Hide mode selector when scrolling a full page down. + if (GW.scrollState.unbrokenDownScrollDistance > window.innerHeight) { + hideModeSelector(); + } + + // On desktop, show mode selector when scrolling to top of page, + // or a full page up. + // On mobile, show mode selector on ANY scroll up. + if (GW.mediaQueries.mobileNarrow.matches) { + if (GW.scrollState.unbrokenUpScrollDistance > 0 || GW.scrollState.lastScrollTop <= 0) + showModeSelector(); + } else if ( GW.scrollState.unbrokenUpScrollDistance > window.innerHeight + || GW.scrollState.lastScrollTop == 0) { + showModeSelector(); + } +} + +function hideModeSelector() { + GWLog("hideModeSelector"); + + GW.scrollState.modeSelector[0].classList.add("hidden"); +} + +function showModeSelector() { + GWLog("showModeSelector"); + + GW.scrollState.modeSelector[0].classList.remove("hidden"); +} + +/* Update the states of the mode selector buttons. + */ +function updateModeSelectorState() { + // Get saved mode setting (or default). + let currentMode = localStorage.getItem("selected-mode") || 'auto'; + + // Clear current buttons state. + let modeSelector = document.querySelector("#mode-selector"); + modeSelector.childNodes.forEach(button => { + button.classList.remove("active", "selected"); + button.disabled = false; + }); + + // Set the correct button to be selected. + modeSelector.querySelectorAll(`.select-mode-${currentMode}`).forEach(button => { + button.classList.add("selected"); + button.disabled = true; + }); + + // Ensure the right button (light or dark) has the “currently active” + // indicator, if the current mode is ‘auto’. + if (currentMode == "auto") { + if (GW.mediaQueries.systemDarkModeActive.matches) + modeSelector.querySelector(".select-mode-dark").classList.add("active"); + else + modeSelector.querySelector(".select-mode-light").classList.add("active"); + } +} + +/* Set specified color mode (auto, light, dark). + */ +function setMode(modeOption) { + GWLog("setMode"); + + // Inject the appropriate styles. + let modeStyles = document.querySelector("#mode-styles"); + if (modeOption == 'auto') { + modeStyles.innerHTML = `@media (prefers-color-scheme:dark) {${GW.modeStyles}}`; + } else if (modeOption == 'dark') { + modeStyles.innerHTML = GW.modeStyles; + } else { + modeStyles.innerHTML = ""; + } + + // Update selector state. + updateModeSelectorState(); +} + +/******************/ +/* INITIALIZATION */ +/******************/ + +doWhenPageLoaded(() => { + injectModeSelector(); +}); diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..5397f41 --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,14 @@ + + + + http://example.org/contact/ + 0 + + http://example.org/categories/ + + http://example.org/ + + http://example.org/tags/ + + diff --git a/public/tags/index.html b/public/tags/index.html new file mode 100644 index 0000000..86aa5e5 --- /dev/null +++ b/public/tags/index.html @@ -0,0 +1,43 @@ + + + Tags | My New Hugo Site + + + + + + + + + + + + + + + + + + + + + +

+ Tags +

+ + + + + + + + + + + diff --git a/public/tags/index.xml b/public/tags/index.xml new file mode 100644 index 0000000..201eda6 --- /dev/null +++ b/public/tags/index.xml @@ -0,0 +1,10 @@ + + + + Tags on My New Hugo Site + http://example.org/tags/ + Recent content in Tags on My New Hugo Site + Hugo -- gohugo.io + en-us + +