Reformatted articles, extracted themes script.
This commit is contained in:
parent
5e9eafe19a
commit
4191903d92
|
@ -6,45 +6,10 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="Articles written by Andrew Lalis.">
|
<meta name="description" content="Articles written by Andrew Lalis.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
|
||||||
|
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
|
||||||
|
|
||||||
<script>
|
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
||||||
// An inline script that manages the site's color theme.
|
<script src="scripts/themes.min.js"></script>
|
||||||
const THEMES = ["light", "dark"];
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -75,6 +40,38 @@
|
||||||
Although I don't generally write much, sometimes I'll find something interesting, or something that I notice a significant number of people could benefit from reading about. In that case, it'll most likely end up on this page as an article.
|
Although I don't generally write much, sometimes I'll find something interesting, or something that I notice a significant number of people could benefit from reading about. In that case, it'll most likely end up on this page as an article.
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<table class="basic-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="min-width: 18ch">Date</th>
|
||||||
|
<th>Article</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Note: Add a new row here for each article. Sorted with newest first. -->
|
||||||
|
<tr>
|
||||||
|
<td><time datetime="2023-02-06">February 6<sup>th</sup>, 2023</time></td>
|
||||||
|
<td><a href="articles/beginner-guide-to-apache-lucene.html">A Beginner's Guide to Searching with Lucene</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><time datetime="2022-05-05">May 5<sup>th</sup>, 2022</time></td>
|
||||||
|
<td><a href="articles/dsh-easier-scripting-in-d.html">DSH - Easier Scripting in D</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><time datetime="2022-03-26">March 26<sup>th</sup>, 2022</time></td>
|
||||||
|
<td><a href="articles/d-prospects-for-future.html">The D Programming Language: Does it have a future?</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><time datetime="2021-05-09">May 9<sup>th</sup>, 2021</time></td>
|
||||||
|
<td><a href="articles/spring-osiv-transactions.html">Spring's Open-Session-in-View & Transactions</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><time datetime="2021-05-09">May 9<sup>th</sup>, 2021</time></td>
|
||||||
|
<td><a href="articles/java-swing-2d-game.html">2D Games with Java & Swing</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,39 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>A Beginner's Guide to Searching With Lucene</title>
|
<title>A Beginner's Guide to Searching With Lucene</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="A simple, easy-to-follow guide that walks you through creating your first index, and searching through it with queries."/>
|
<meta name="description" content="A simple, easy-to-follow guide that walks you through creating your first index, and searching through it with queries."/>
|
||||||
<link rel="stylesheet" href="../../css/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../../css/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
<link rel="stylesheet" href="../../css/blog-article.css" type="text/css"/>
|
<script src="../scripts/themes.min.js"></script>
|
||||||
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../styles/article.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header class="page-header">
|
||||||
|
<h1>Andrew's Articles</h1>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<a href="../index.html">Home</a>
|
||||||
|
<a class="page-header-selected" href="../articles.html">Articles</a>
|
||||||
|
<a href="../projects.html">Projects</a>
|
||||||
|
<a href="../training.html">Training</a>
|
||||||
|
<a href="../contact.html">Contact</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://github.com/andrewlalis">GitHub</a>
|
||||||
|
<a href="https://www.linkedin.com/in/andrew-lalis/">LinkedIn</a>
|
||||||
|
<a href="https://www.youtube.com/channel/UC9X4mx6-ObPUB6-ud2IGAFQ">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button id="themeToggleButton" class="jsonly">Change Color Theme</button>
|
||||||
|
<hr>
|
||||||
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1>A Beginner's Guide to Searching With Lucene</h1>
|
<h1>A Beginner's Guide to Searching With Lucene</h1>
|
||||||
|
@ -27,7 +53,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>The Use Case</h3>
|
<h2>The Use Case</h2>
|
||||||
<p>
|
<p>
|
||||||
Before we dive into the code, it's important to make sure that you actually need an indexing and searching tool that goes beyond simple SQL queries.
|
Before we dive into the code, it's important to make sure that you actually need an indexing and searching tool that goes beyond simple SQL queries.
|
||||||
</p>
|
</p>
|
||||||
|
@ -42,7 +68,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Indexing and Searching Basics</h3>
|
<h2>Indexing and Searching Basics</h2>
|
||||||
<p>
|
<p>
|
||||||
No matter what searching solution you end up choosing, they all generally follow the same approach:
|
No matter what searching solution you end up choosing, they all generally follow the same approach:
|
||||||
</p>
|
</p>
|
||||||
|
@ -64,7 +90,7 @@
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3>Setting Up a New Project</h3>
|
<h2>Setting Up a New Project</h2>
|
||||||
<p>
|
<p>
|
||||||
In this guide, I'll be creating a small Java program for searching over a huge set of airports which is available for free here: <a class="link_external" target="_blank" href="https://ourairports.com/data/">https://ourairports.com/data/</a>. The full source code for this project is <a class="link_external" target="_blank" href="https://github.com/andrewlalis/SampleLuceneSearch">available on GitHub</a>, if you'd like to take a look.
|
In this guide, I'll be creating a small Java program for searching over a huge set of airports which is available for free here: <a class="link_external" target="_blank" href="https://ourairports.com/data/">https://ourairports.com/data/</a>. The full source code for this project is <a class="link_external" target="_blank" href="https://github.com/andrewlalis/SampleLuceneSearch">available on GitHub</a>, if you'd like to take a look.
|
||||||
</p>
|
</p>
|
||||||
|
@ -94,7 +120,7 @@
|
||||||
</figure>
|
</figure>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Parsing the Data</h3>
|
<h2>Parsing the Data</h2>
|
||||||
<p>
|
<p>
|
||||||
First of all, we need to parse the CSV data into a programming construct that we can use elsewhere in our code. In this case, I've defined the <code>Airport</code> record like so:
|
First of all, we need to parse the CSV data into a programming construct that we can use elsewhere in our code. In this case, I've defined the <code>Airport</code> record like so:
|
||||||
</p>
|
</p>
|
||||||
|
@ -131,7 +157,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3>Indexing</h3>
|
<h2>Indexing</h2>
|
||||||
<p>
|
<p>
|
||||||
In order to efficiently search over a massive set of data, we need to prepare a special set of index files that Lucene can read during searches. To do that, we need to create a new directory for the index to live in, construct a new <a class="link_external" target="_blank" href="https://javadoc.io/doc/org.apache.lucene/lucene-core/latest/org/apache/lucene/index/IndexWriter.html">IndexWriter</a>, and create a <a class="link_external" target="_blank" href="https://javadoc.io/doc/org.apache.lucene/lucene-core/latest/org/apache/lucene/document/Document.html">Document</a> for each airport we're indexing.
|
In order to efficiently search over a massive set of data, we need to prepare a special set of index files that Lucene can read during searches. To do that, we need to create a new directory for the index to live in, construct a new <a class="link_external" target="_blank" href="https://javadoc.io/doc/org.apache.lucene/lucene-core/latest/org/apache/lucene/index/IndexWriter.html">IndexWriter</a>, and create a <a class="link_external" target="_blank" href="https://javadoc.io/doc/org.apache.lucene/lucene-core/latest/org/apache/lucene/document/Document.html">Document</a> for each airport we're indexing.
|
||||||
</p>
|
</p>
|
||||||
|
@ -187,7 +213,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3>Searching</h3>
|
<h2>Searching</h2>
|
||||||
<p>
|
<p>
|
||||||
Now that we've built an index from our dataset, we can search over it to find the most relevant results for a user's query.
|
Now that we've built an index from our dataset, we can search over it to find the most relevant results for a user's query.
|
||||||
</p>
|
</p>
|
||||||
|
@ -260,12 +286,9 @@
|
||||||
<p>
|
<p>
|
||||||
Once again, my sample code is <a class="link_external" target="_blank" href="https://github.com/andrewlalis/SampleLuceneSearch">available on GitHub here</a>.
|
Once again, my sample code is <a class="link_external" target="_blank" href="https://github.com/andrewlalis/SampleLuceneSearch">available on GitHub here</a>.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
<a href="../articles.html">Back to Articles</a>
|
||||||
|
|
||||||
<a href="../blog.html">Back to Dev Discussions</a>
|
|
||||||
</article>
|
</article>
|
||||||
<script src="../../js/prism.js"></script>
|
<script src="../vendor/prism.js"></script>
|
||||||
<script src="../../js/themes.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,13 +4,39 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>The D Programming Language: Does it have a future?</title>
|
<title>The D Programming Language: Does it have a future?</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="Discussion around the D programming language and its potential and future as a general language."/>
|
<meta name="description" content="Discussion around the D programming language and its potential and future as a general language."/>
|
||||||
<link rel="stylesheet" href="../../css/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../../css/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
<link rel="stylesheet" href="../../css/blog-article.css" type="text/css"/>
|
<script src="../scripts/themes.min.js"></script>
|
||||||
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../styles/article.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header class="page-header">
|
||||||
|
<h1>Andrew's Articles</h1>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<a href="../index.html">Home</a>
|
||||||
|
<a class="page-header-selected" href="../articles.html">Articles</a>
|
||||||
|
<a href="../projects.html">Projects</a>
|
||||||
|
<a href="../training.html">Training</a>
|
||||||
|
<a href="../contact.html">Contact</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://github.com/andrewlalis">GitHub</a>
|
||||||
|
<a href="https://www.linkedin.com/in/andrew-lalis/">LinkedIn</a>
|
||||||
|
<a href="https://www.youtube.com/channel/UC9X4mx6-ObPUB6-ud2IGAFQ">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button id="themeToggleButton" class="jsonly">Change Color Theme</button>
|
||||||
|
<hr>
|
||||||
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1>The D Programming Language: Does it have a future?</h1>
|
<h1>The D Programming Language: Does it have a future?</h1>
|
||||||
|
@ -25,7 +51,7 @@
|
||||||
a radical stance, and contrast those ideals with some harsh realities.
|
a radical stance, and contrast those ideals with some harsh realities.
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>The Potential</h3>
|
<h2>The Potential</h2>
|
||||||
<p>
|
<p>
|
||||||
Because it was designed many years after the advent of most of the main programming languages that form the
|
Because it was designed many years after the advent of most of the main programming languages that form the
|
||||||
backbone of our software (C, C++, Java, Python, etc.), D has the benefit of 20/20 hindsight that it uses to
|
backbone of our software (C, C++, Java, Python, etc.), D has the benefit of 20/20 hindsight that it uses to
|
||||||
|
@ -95,13 +121,13 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Why Isn't D Popular?</h3>
|
<h2>Why Isn't D Popular?</h2>
|
||||||
<p>
|
<p>
|
||||||
You'd think that all these benefits, developers would be flocking in droves to D. But clearly in the real
|
You'd think that all these benefits, developers would be flocking in droves to D. But clearly in the real
|
||||||
world, that's not the case. <strong>Why?</strong> This section outlines some of the reasons why the language
|
world, that's not the case. <strong>Why?</strong> This section outlines some of the reasons why the language
|
||||||
hasn't attained the same level of popularity as others.
|
hasn't attained the same level of popularity as others.
|
||||||
</p>
|
</p>
|
||||||
<h4>Late to the Party</h4>
|
<h3>Late to the Party</h3>
|
||||||
<p>
|
<p>
|
||||||
Despite their modern-day popularity, all of the major programming languages are several decades old: Java
|
Despite their modern-day popularity, all of the major programming languages are several decades old: Java
|
||||||
was created in 1995, Python in 1991, C++ in 1985, and so on. D was first conceived in 2001, giving all of
|
was created in 1995, Python in 1991, C++ in 1985, and so on. D was first conceived in 2001, giving all of
|
||||||
|
@ -111,7 +137,7 @@
|
||||||
from there. So we're dealing with a relatively immature language as of yet, which still needs to prove its
|
from there. So we're dealing with a relatively immature language as of yet, which still needs to prove its
|
||||||
worthiness in various disciplines before it gains popularity.
|
worthiness in various disciplines before it gains popularity.
|
||||||
</p>
|
</p>
|
||||||
<h4>Paradoxical Loneliness</h4>
|
<h3>Paradoxical Loneliness</h3>
|
||||||
<p>
|
<p>
|
||||||
One fatal issue which affects many software projects is this: the project receives little attention from new
|
One fatal issue which affects many software projects is this: the project receives little attention from new
|
||||||
users, so it is not promoted to new users. Therefore, the project yet again receives little attention from
|
users, so it is not promoted to new users. Therefore, the project yet again receives little attention from
|
||||||
|
@ -122,7 +148,7 @@
|
||||||
languages but instead offers smaller meaningful, incremental improvements, it's also not the most flashy
|
languages but instead offers smaller meaningful, incremental improvements, it's also not the most flashy
|
||||||
new language for individual developers to rave about in the free time.
|
new language for individual developers to rave about in the free time.
|
||||||
</p>
|
</p>
|
||||||
<h4>A New Ecosystem</h4>
|
<h3>A New Ecosystem</h3>
|
||||||
<p>
|
<p>
|
||||||
Stemming from the other reasons mentioned above, because D is relatively new, its software ecosystem is
|
Stemming from the other reasons mentioned above, because D is relatively new, its software ecosystem is
|
||||||
still growing, and lacks some of the mature, standard libraries we've come to expect from a general-purpose
|
still growing, and lacks some of the mature, standard libraries we've come to expect from a general-purpose
|
||||||
|
@ -131,9 +157,8 @@
|
||||||
robust library of modules that rivals the Java and C++ ecosystems.
|
robust library of modules that rivals the Java and C++ ecosystems.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<a href="../blog.html">Back to Dev Discussions</a>
|
<a href="../articles.html">Back to Articles</a>
|
||||||
</article>
|
</article>
|
||||||
<script src="../../js/prism.js"></script>
|
<script src="../vendor/prism.js"></script>
|
||||||
<script src="../../js/themes.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,12 +4,37 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>DSH - Easier Scripting in D</title>
|
<title>DSH - Easier Scripting in D</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="DSH is a library I developed to make it easier to write scripts in the D programming language."/>
|
<meta name="description" content="DSH is a library I developed to make it easier to write scripts in the D programming language."/>
|
||||||
<link rel="stylesheet" href="../../css/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../../css/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
<link rel="stylesheet" href="../../css/blog-article.css" type="text/css"/>
|
<script src="../scripts/themes.min.js"></script>
|
||||||
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../styles/article.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<header class="page-header">
|
||||||
|
<h1>Andrew's Articles</h1>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<a href="../index.html">Home</a>
|
||||||
|
<a class="page-header-selected" href="../articles.html">Articles</a>
|
||||||
|
<a href="../projects.html">Projects</a>
|
||||||
|
<a href="../training.html">Training</a>
|
||||||
|
<a href="../contact.html">Contact</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://github.com/andrewlalis">GitHub</a>
|
||||||
|
<a href="https://www.linkedin.com/in/andrew-lalis/">LinkedIn</a>
|
||||||
|
<a href="https://www.youtube.com/channel/UC9X4mx6-ObPUB6-ud2IGAFQ">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button id="themeToggleButton" class="jsonly">Change Color Theme</button>
|
||||||
|
<hr>
|
||||||
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
|
@ -27,7 +52,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Why write scripts in D?</h3>
|
<h2>Why write scripts in D?</h2>
|
||||||
<p>
|
<p>
|
||||||
While many people are used to scripting in languages that have been built over the years specifically for that use case, this introduces extra complexity into projects that are mainly built using some other language. In an ideal world, we'd use one single language to describe everything about our app, from the way it looks, to how we compile and distribute it. DSH is my attempt to make this a reality, at least for applications written in D. When developing D programs that require some auxiliary scripts, you don't have to make a cognitive jump to another language; just keep writing code in the environment you're most efficient in. This way, we reap the benefits of specializing in becoming an expert in a single language and its ecosystem.
|
While many people are used to scripting in languages that have been built over the years specifically for that use case, this introduces extra complexity into projects that are mainly built using some other language. In an ideal world, we'd use one single language to describe everything about our app, from the way it looks, to how we compile and distribute it. DSH is my attempt to make this a reality, at least for applications written in D. When developing D programs that require some auxiliary scripts, you don't have to make a cognitive jump to another language; just keep writing code in the environment you're most efficient in. This way, we reap the benefits of specializing in becoming an expert in a single language and its ecosystem.
|
||||||
</p>
|
</p>
|
||||||
|
@ -36,7 +61,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Writing Your Script</h3>
|
<h2>Writing Your Script</h2>
|
||||||
<p>
|
<p>
|
||||||
There are two main ways to write scripts using DSH:
|
There are two main ways to write scripts using DSH:
|
||||||
</p>
|
</p>
|
||||||
|
@ -86,12 +111,12 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3>Helper Functions</h3>
|
<h2>Helper Functions</h2>
|
||||||
<p>
|
<p>
|
||||||
While dshutil is a handy tool on its own, the real benefit of using DSH is its library of helper functions which are designed specifically for scripting tasks.
|
While dshutil is a handy tool on its own, the real benefit of using DSH is its library of helper functions which are designed specifically for scripting tasks.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>File Utilities</h4>
|
<h3>File Utilities</h3>
|
||||||
<p>
|
<p>
|
||||||
DSH offers quite a few helpful functions that reduce the verbosity of your IO operations. Below is a sampling of some of the most prominent functions.
|
DSH offers quite a few helpful functions that reduce the verbosity of your IO operations. Below is a sampling of some of the most prominent functions.
|
||||||
</p>
|
</p>
|
||||||
|
@ -108,7 +133,7 @@
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h4>Process Utilities</h4>
|
<h3>Process Utilities</h3>
|
||||||
<p>
|
<p>
|
||||||
In addition to the functions in D's <code>std.process</code> module, DSH provides some shortcuts for scripts to make it easy to manage processes.
|
In addition to the functions in D's <code>std.process</code> module, DSH provides some shortcuts for scripts to make it easy to manage processes.
|
||||||
</p>
|
</p>
|
||||||
|
@ -126,9 +151,8 @@
|
||||||
Also included is a <code>ProcessBuilder</code> class with which you can use a fluent method interface to construct processes with custom input and output sources and environments.
|
Also included is a <code>ProcessBuilder</code> class with which you can use a fluent method interface to construct processes with custom input and output sources and environments.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<a href="../blog.html">Back to Dev Discussions</a>
|
<a href="../articles.html">Back to Articles</a>
|
||||||
</article>
|
</article>
|
||||||
<script src="../../js/prism.js"></script>
|
<script src="../vendor/prism.js"></script>
|
||||||
<script src="../../js/themes.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,13 +4,39 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Java + Swing 2D Games</title>
|
<title>Java + Swing 2D Games</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="Important information for programmers who want to make simple 2D games with Java using the Swing framework."/>
|
<meta name="description" content="Important information for programmers who want to make simple 2D games with Java using the Swing framework."/>
|
||||||
<link rel="stylesheet" href="../../css/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../../css/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
<link rel="stylesheet" href="../../css/blog-article.css" type="text/css"/>
|
<script src="../scripts/themes.min.js"></script>
|
||||||
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../styles/article.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header class="page-header">
|
||||||
|
<h1>Andrew's Articles</h1>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<a href="../index.html">Home</a>
|
||||||
|
<a class="page-header-selected" href="../articles.html">Articles</a>
|
||||||
|
<a href="../projects.html">Projects</a>
|
||||||
|
<a href="../training.html">Training</a>
|
||||||
|
<a href="../contact.html">Contact</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://github.com/andrewlalis">GitHub</a>
|
||||||
|
<a href="https://www.linkedin.com/in/andrew-lalis/">LinkedIn</a>
|
||||||
|
<a href="https://www.youtube.com/channel/UC9X4mx6-ObPUB6-ud2IGAFQ">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button id="themeToggleButton" class="jsonly">Change Color Theme</button>
|
||||||
|
<hr>
|
||||||
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1>2D Game Development with Java and Swing</h1>
|
<h1>2D Game Development with Java and Swing</h1>
|
||||||
|
@ -35,7 +61,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section id="mvc">
|
<section id="mvc">
|
||||||
<h3>Model-View-Control Design</h3>
|
<h2>Model-View-Control Design</h2>
|
||||||
<p>
|
<p>
|
||||||
At first, it's super easy to make a new JFrame and start drawing on it, and you can add action listeners everywhere, whenever they're needed. If you ever plan on expanding beyond a simple 20-line drawing method however, you should organize your code using the <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a> pattern. For example, in my <a href="https://github.com/andrewlalis/BeforeAsteroids/tree/main/src/main/java/nl/andrewlalis"><em>Before Asteroids</em></a> sample game, I have split up my code into a few different packages.
|
At first, it's super easy to make a new JFrame and start drawing on it, and you can add action listeners everywhere, whenever they're needed. If you ever plan on expanding beyond a simple 20-line drawing method however, you should organize your code using the <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a> pattern. For example, in my <a href="https://github.com/andrewlalis/BeforeAsteroids/tree/main/src/main/java/nl/andrewlalis"><em>Before Asteroids</em></a> sample game, I have split up my code into a few different packages.
|
||||||
</p>
|
</p>
|
||||||
|
@ -54,7 +80,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section id="swing_setup">
|
<section id="swing_setup">
|
||||||
<h3>Setting up a Swing GUI</h3>
|
<h2>Setting up a Swing GUI</h2>
|
||||||
<p>
|
<p>
|
||||||
Making a Swing GUI usually consists of two basic components: the <strong>JFrame</strong> that acts as your application's window, and a <strong>JPanel</strong> that is used for actually drawing your model. Usually we start by defining our own frame to extend from the base JFrame, and set its properties in a constructor.
|
Making a Swing GUI usually consists of two basic components: the <strong>JFrame</strong> that acts as your application's window, and a <strong>JPanel</strong> that is used for actually drawing your model. Usually we start by defining our own frame to extend from the base JFrame, and set its properties in a constructor.
|
||||||
</p>
|
</p>
|
||||||
|
@ -105,7 +131,7 @@
|
||||||
</figure>
|
</figure>
|
||||||
</section>
|
</section>
|
||||||
<section id="game_loop">
|
<section id="game_loop">
|
||||||
<h3>The Game Loop</h3>
|
<h2>The Game Loop</h2>
|
||||||
<p>
|
<p>
|
||||||
First of all, this guide won't go too in-depth about the details of game loops in general, but focuses specifically on their implementation with Java/Swing. For more information, you can read <a href="https://gameprogrammingpatterns.com/game-loop.html">this excellent article on the subject</a>.
|
First of all, this guide won't go too in-depth about the details of game loops in general, but focuses specifically on their implementation with Java/Swing. For more information, you can read <a href="https://gameprogrammingpatterns.com/game-loop.html">this excellent article on the subject</a>.
|
||||||
</p>
|
</p>
|
||||||
|
@ -202,7 +228,7 @@
|
||||||
</figure>
|
</figure>
|
||||||
</section>
|
</section>
|
||||||
<section id="listeners">
|
<section id="listeners">
|
||||||
<h3>Listeners and Control</h3>
|
<h2>Listeners and Control</h2>
|
||||||
<p>
|
<p>
|
||||||
Most often, you'll want something to happen when the player presses a key or clicks the mouse. To do this, you should create your own class which extends from <a href="https://docs.oracle.com/javase/8/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter</a> or <a href="https://docs.oracle.com/javase/8/docs/api/java/awt/event/MouseAdapter.html">MouseAdapter</a>, depending on what you want to do.
|
Most often, you'll want something to happen when the player presses a key or clicks the mouse. To do this, you should create your own class which extends from <a href="https://docs.oracle.com/javase/8/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter</a> or <a href="https://docs.oracle.com/javase/8/docs/api/java/awt/event/MouseAdapter.html">MouseAdapter</a>, depending on what you want to do.
|
||||||
<br>
|
<br>
|
||||||
|
@ -244,9 +270,8 @@
|
||||||
<figcaption>In this example, I show both checking which button was pressed, and also checking where the button was pressed. <code>getX()</code> and <code>getY()</code> return the x- and y-coordinates relative to the <em>source component</em>, which will most often be the JFrame or JPanel that the user clicked on.</figcaption>
|
<figcaption>In this example, I show both checking which button was pressed, and also checking where the button was pressed. <code>getX()</code> and <code>getY()</code> return the x- and y-coordinates relative to the <em>source component</em>, which will most often be the JFrame or JPanel that the user clicked on.</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
</section>
|
</section>
|
||||||
<a href="../blog.html">Back to Dev Discussions</a>
|
<a href="../articles.html">Back to Articles</a>
|
||||||
</article>
|
</article>
|
||||||
<script src="../../js/prism.js"></script>
|
<script src="../vendor/prism.js"></script>
|
||||||
<script src="../../js/themes.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,12 +4,37 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Spring's Open-Session-in-View & Transactions</title>
|
<title>Spring's Open-Session-in-View & Transactions</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="Some explanation about Spring Boot's open-session-in-view setting and how to get around it."/>
|
<meta name="description" content="Some explanation about Spring Boot's open-session-in-view setting and how to get around it."/>
|
||||||
<link rel="stylesheet" href="../../css/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../../css/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
<link rel="stylesheet" href="../../css/blog-article.css" type="text/css"/>
|
<script src="../scripts/themes.min.js"></script>
|
||||||
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../styles/article.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<header class="page-header">
|
||||||
|
<h1>Andrew's Articles</h1>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<a href="../index.html">Home</a>
|
||||||
|
<a class="page-header-selected" href="../articles.html">Articles</a>
|
||||||
|
<a href="../projects.html">Projects</a>
|
||||||
|
<a href="../training.html">Training</a>
|
||||||
|
<a href="../contact.html">Contact</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://github.com/andrewlalis">GitHub</a>
|
||||||
|
<a href="https://www.linkedin.com/in/andrew-lalis/">LinkedIn</a>
|
||||||
|
<a href="https://www.youtube.com/channel/UC9X4mx6-ObPUB6-ud2IGAFQ">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button id="themeToggleButton" class="jsonly">Change Color Theme</button>
|
||||||
|
<hr>
|
||||||
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
|
@ -27,7 +52,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Don't Send Entities to Your View</h3>
|
<h2>Don't Send Entities to Your View</h2>
|
||||||
<p>
|
<p>
|
||||||
At first, many of the simple tutorials you'll read online will have you passing your entity models to Thymeleaf or JSP templates to render a web page for your application. This convenience is what leads developers to use OSIV in the first place, because they start fetching attributes of their entity which were not initially loaded. This is fine for the most simple "Hello World" starter projects, but as soon as you add any real complexity, this "convenience" breaks down into an unorganized mess, where it is not clear at a glance where data will be fetched from the database.
|
At first, many of the simple tutorials you'll read online will have you passing your entity models to Thymeleaf or JSP templates to render a web page for your application. This convenience is what leads developers to use OSIV in the first place, because they start fetching attributes of their entity which were not initially loaded. This is fine for the most simple "Hello World" starter projects, but as soon as you add any real complexity, this "convenience" breaks down into an unorganized mess, where it is not clear at a glance where data will be fetched from the database.
|
||||||
</p>
|
</p>
|
||||||
|
@ -49,7 +74,7 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h3>Transactions</h3>
|
<h2>Transactions</h2>
|
||||||
<p>
|
<p>
|
||||||
The Spring framework allows you to annotate a service's method as <code>@Transactional</code>, which means that at runtime, when your method is called, a proxy method is wrapped around it which starts a transaction (and thus a Hibernate session to go with it) that persists for the duration of the method. Inside this method, you are free to fetch lazy-loaded attributes from an entity, without having to deal with LazyInitializationExceptions.
|
The Spring framework allows you to annotate a service's method as <code>@Transactional</code>, which means that at runtime, when your method is called, a proxy method is wrapped around it which starts a transaction (and thus a Hibernate session to go with it) that persists for the duration of the method. Inside this method, you are free to fetch lazy-loaded attributes from an entity, without having to deal with LazyInitializationExceptions.
|
||||||
</p>
|
</p>
|
||||||
|
@ -73,9 +98,8 @@
|
||||||
However, the flexibility of being able to use lazy-loaded attributes the easy way more than makes up for the strict encapsulation rules, and by structuring your project around service methods as black-box operations, you'll be able to build huge projects while keeping your sanity mostly intact.
|
However, the flexibility of being able to use lazy-loaded attributes the easy way more than makes up for the strict encapsulation rules, and by structuring your project around service methods as black-box operations, you'll be able to build huge projects while keeping your sanity mostly intact.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<a href="../blog.html">Back to Dev Discussions</a>
|
<a href="../articles.html">Back to Articles</a>
|
||||||
</article>
|
</article>
|
||||||
<script src="../../js/prism.js"></script>
|
<script src="../vendor/prism.js"></script>
|
||||||
<script src="../../js/themes.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,50 +4,16 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{TEMPLATE_TITLE}}</title>
|
<title>{{TEMPLATE_TITLE}}</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="{{TEMPLATE_DESCRIPTION}}"/>
|
<meta name="description" content="{{TEMPLATE_DESCRIPTION}}"/>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
<link rel="stylesheet" href="../styles/font.css" type="text/css">
|
||||||
|
<script src="../scripts/themes.min.js"></script>
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
<link rel="stylesheet" href="../styles/style.css" type="text/css">
|
||||||
|
|
||||||
<script>
|
|
||||||
// An inline script that manages the site's color theme.
|
|
||||||
const THEMES = ["light", "dark"];
|
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="../styles/style.css" type="text/css"/>
|
|
||||||
<link rel="stylesheet" href="../styles/article.css" type="text/css"/>
|
<link rel="stylesheet" href="../styles/article.css" type="text/css"/>
|
||||||
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
<link rel="stylesheet" href="../vendor/prism.css" type="text/css"/>
|
||||||
<script src="../vendor/prism.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
@ -118,7 +84,8 @@
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</figure>
|
</figure>
|
||||||
</section>
|
</section>
|
||||||
|
<a href="../articles.html">Back to Articles</a>
|
||||||
</article>
|
</article>
|
||||||
|
<script src="../vendor/prism.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
41
contact.html
41
contact.html
|
@ -6,45 +6,10 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="Contact information for Andrew Lalis.">
|
<meta name="description" content="Contact information for Andrew Lalis.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
|
||||||
|
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
|
||||||
|
|
||||||
<script>
|
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
||||||
// An inline script that manages the site's color theme.
|
<script src="scripts/themes.min.js"></script>
|
||||||
const THEMES = ["light", "dark"];
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
41
index.html
41
index.html
|
@ -6,45 +6,10 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="The Homepage of Andrew Lalis.">
|
<meta name="description" content="The Homepage of Andrew Lalis.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
||||||
|
<script src="scripts/themes.min.js"></script>
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
|
||||||
<script>
|
|
||||||
// An inline script that manages the site's color theme.
|
|
||||||
const THEMES = ["light", "dark"];
|
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -79,7 +44,7 @@
|
||||||
<article>
|
<article>
|
||||||
<h2>About this Site</h2>
|
<h2>About this Site</h2>
|
||||||
<p>
|
<p>
|
||||||
This page was written by me, Andrew Lalis, to be my personal website on the world-wide-web. It's got all the usual stuff that a personal site should have, like important links and contact details, plus a little series of articles I've written about my experiences with programming, lifting, gaming, or anything else of interest.
|
This page was hand-written by me, Andrew Lalis, to be my personal website on the world-wide-web. It's got all the usual stuff that a personal site should have, like important links and contact details, plus a little series of articles I've written about my experiences with programming, lifting, gaming, or anything else of interest.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
As you can see, I'm a fan of the <em>"plain HTML is responsive"</em> school of thought. This website is intentionally very simple in its structure, styling, and interactivity. This is because I believe that the vast majority of the internet's most popular websites sacrifice usability and accessibility to make a flashier product. By using a simpler design, we can help to make the internet more accessible to all, regardless of their physical ability or device's processing power.
|
As you can see, I'm a fan of the <em>"plain HTML is responsive"</em> school of thought. This website is intentionally very simple in its structure, styling, and interactivity. This is because I believe that the vast majority of the internet's most popular websites sacrifice usability and accessibility to make a flashier product. By using a simpler design, we can help to make the internet more accessible to all, regardless of their physical ability or device's processing power.
|
||||||
|
|
|
@ -6,46 +6,12 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="The Homepage of Andrew Lalis.">
|
<meta name="description" content="The Homepage of Andrew Lalis.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
|
||||||
|
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
|
||||||
|
|
||||||
<script>
|
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
||||||
// An inline script that manages the site's color theme.
|
<script src="scripts/themes.min.js"></script>
|
||||||
const THEMES = ["light", "dark"];
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/project.css" type="text/css">
|
<link rel="stylesheet" href="styles/project.css" type="text/css">
|
||||||
<link rel="stylesheet" href="vendor/prism.css" data-noprefix>
|
<link rel="stylesheet" href="vendor/prism.css" data-noprefix>
|
||||||
<script src="vendor/prism.js"></script>
|
<script src="vendor/prism.js"></script>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
const THEMES = ["light", "dark"];
|
||||||
|
|
||||||
|
function getPreferredTheme() {
|
||||||
|
const storedTheme = localStorage.getItem("theme");
|
||||||
|
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
||||||
|
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
|
return "dark";
|
||||||
|
}
|
||||||
|
return "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPreferredTheme(theme) {
|
||||||
|
document.documentElement.className = theme;
|
||||||
|
localStorage.setItem("theme", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPreferredTheme(getPreferredTheme());
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
||||||
|
const newTheme = event.matches ? "dark" : "light";
|
||||||
|
setPreferredTheme(newTheme);
|
||||||
|
});
|
||||||
|
document.addEventListener("DOMContentLoaded", event => {
|
||||||
|
const themeToggleButton = document.getElementById("themeToggleButton");
|
||||||
|
themeToggleButton.onclick = clickEvent => {
|
||||||
|
const currentTheme = getPreferredTheme();
|
||||||
|
const idx = THEMES.indexOf(currentTheme);
|
||||||
|
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
||||||
|
setPreferredTheme(THEMES[nextIdx]);
|
||||||
|
};
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
const THEMES=["light","dark"];function getPreferredTheme(){const e=localStorage.getItem("theme");return null!==e&&THEMES.includes(e)?e:window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function setPreferredTheme(e){document.documentElement.className=e,localStorage.setItem("theme",e)}setPreferredTheme(getPreferredTheme()),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",(e=>{setPreferredTheme(e.matches?"dark":"light")})),document.addEventListener("DOMContentLoaded",(e=>{document.getElementById("themeToggleButton").onclick=e=>{const t=getPreferredTheme(),r=THEMES.indexOf(t),d=r===THEMES.length-1?0:r+1;setPreferredTheme(THEMES[d])}}));
|
|
@ -1,5 +1,11 @@
|
||||||
article {
|
article {
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
article h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: xx-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
|
|
|
@ -46,7 +46,6 @@ code {
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
border: 1px solid blue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-table th {
|
.stats-table th {
|
||||||
|
@ -79,3 +78,22 @@ code {
|
||||||
.page-header-selected {
|
.page-header-selected {
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.basic-table {
|
||||||
|
background-color: var(--background-color-2);
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basic-table th {
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid var(--background-color-3);
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basic-table td {
|
||||||
|
font-family: "IBM Plex Sans";
|
||||||
|
text-align: start;
|
||||||
|
border: 1px solid var(--background-color-3);
|
||||||
|
padding: 0.25em;
|
||||||
|
}
|
||||||
|
|
|
@ -6,45 +6,10 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="An overview of Andrew's lifting, endurance, and other athletic achievements.">
|
<meta name="description" content="An overview of Andrew's lifting, endurance, and other athletic achievements.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
|
||||||
|
|
||||||
<!-- CSS class to hide elements if JS is not enabled. -->
|
|
||||||
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
|
||||||
|
|
||||||
<script>
|
<link rel="stylesheet" href="styles/font.css" type="text/css">
|
||||||
// An inline script that manages the site's color theme.
|
<script src="scripts/themes.min.js"></script>
|
||||||
const THEMES = ["light", "dark"];
|
<noscript><style>.jsonly{display: none !important;}</style></noscript>
|
||||||
|
|
||||||
function getPreferredTheme() {
|
|
||||||
const storedTheme = localStorage.getItem("theme");
|
|
||||||
if (storedTheme !== null && THEMES.includes(storedTheme)) return storedTheme;
|
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
||||||
return "dark";
|
|
||||||
}
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPreferredTheme(theme) {
|
|
||||||
document.documentElement.className = theme;
|
|
||||||
localStorage.setItem("theme", theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPreferredTheme(getPreferredTheme());
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
|
||||||
const newTheme = event.matches ? "dark" : "light";
|
|
||||||
setPreferredTheme(newTheme);
|
|
||||||
});
|
|
||||||
document.addEventListener("DOMContentLoaded", event => {
|
|
||||||
const themeToggleButton = document.getElementById("themeToggleButton");
|
|
||||||
themeToggleButton.onclick = clickEvent => {
|
|
||||||
const currentTheme = getPreferredTheme();
|
|
||||||
const idx = THEMES.indexOf(currentTheme);
|
|
||||||
const nextIdx = idx === THEMES.length - 1 ? 0 : idx + 1;
|
|
||||||
setPreferredTheme(THEMES[nextIdx]);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
<link rel="stylesheet" href="styles/style.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Helper script that copies files to the server.
|
# Helper script that copies files to the server.
|
||||||
# You need to have authenticated access to the server via SSH to use this.
|
# You need to have authenticated access to the server via SSH to use this.
|
||||||
|
|
||||||
rsync -rav -e ssh \
|
rsync -rav -e ssh --delete \
|
||||||
--exclude .git/ --exclude *.sh --exclude README.md \
|
--exclude .git/ --exclude *.sh --exclude README.md \
|
||||||
./ \
|
./ \
|
||||||
root@andrewlalis.com:/var/www/andrewlalis.com/html
|
root@andrewlalis.com:/var/www/andrewlalis.com/html
|
||||||
|
|
Loading…
Reference in New Issue