feat: add Journal page
@@ -2,10 +2,14 @@ import mdx from '@astrojs/mdx';
|
|||||||
import preact from '@astrojs/preact';
|
import preact from '@astrojs/preact';
|
||||||
import tailwind from '@astrojs/tailwind';
|
import tailwind from '@astrojs/tailwind';
|
||||||
import { astroImageTools } from 'astro-imagetools';
|
import { astroImageTools } from 'astro-imagetools';
|
||||||
|
import { remarkReadingTime } from './src/utils';
|
||||||
|
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
markdown: {
|
||||||
|
remarkPlugins: [remarkReadingTime],
|
||||||
|
},
|
||||||
integrations: [mdx(), tailwind(), preact(), astroImageTools],
|
integrations: [mdx(), tailwind(), preact(), astroImageTools],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,14 +22,19 @@
|
|||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"file-type": "^18.4.0",
|
"file-type": "^18.4.0",
|
||||||
"find-cache-dir": "^4.0.0",
|
"find-cache-dir": "^4.0.0",
|
||||||
|
"mdast-util-to-string": "^3.2.0",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"object-hash": "^3.0.0",
|
"object-hash": "^3.0.0",
|
||||||
"postcss": "^8.4.24",
|
"postcss": "^8.4.24",
|
||||||
"potrace": "^2.1.8",
|
"potrace": "^2.1.8",
|
||||||
"preact": "^10.15.1",
|
"preact": "^10.15.1",
|
||||||
|
"reading-time": "^1.5.0",
|
||||||
"sharp": "^0.32.1",
|
"sharp": "^0.32.1",
|
||||||
"tailwindcss": "^3.3.2"
|
"tailwindcss": "^3.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/mdast": "^3.0.11",
|
||||||
|
"@types/unist": "^2.0.6",
|
||||||
"@typescript-eslint/parser": "^5.59.7",
|
"@typescript-eslint/parser": "^5.59.7",
|
||||||
"cssnano": "^6.0.1",
|
"cssnano": "^6.0.1",
|
||||||
"eslint": "^8.41.0",
|
"eslint": "^8.41.0",
|
||||||
|
|||||||
31
pnpm-lock.yaml
generated
@@ -1,4 +1,8 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.1'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/mdx':
|
'@astrojs/mdx':
|
||||||
@@ -31,6 +35,12 @@ dependencies:
|
|||||||
find-cache-dir:
|
find-cache-dir:
|
||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
|
mdast-util-to-string:
|
||||||
|
specifier: ^3.2.0
|
||||||
|
version: 3.2.0
|
||||||
|
moment:
|
||||||
|
specifier: ^2.29.4
|
||||||
|
version: 2.29.4
|
||||||
object-hash:
|
object-hash:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
@@ -43,6 +53,9 @@ dependencies:
|
|||||||
preact:
|
preact:
|
||||||
specifier: ^10.15.1
|
specifier: ^10.15.1
|
||||||
version: 10.15.1
|
version: 10.15.1
|
||||||
|
reading-time:
|
||||||
|
specifier: ^1.5.0
|
||||||
|
version: 1.5.0
|
||||||
sharp:
|
sharp:
|
||||||
specifier: ^0.32.1
|
specifier: ^0.32.1
|
||||||
version: 0.32.1
|
version: 0.32.1
|
||||||
@@ -51,6 +64,12 @@ dependencies:
|
|||||||
version: 3.3.2
|
version: 3.3.2
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@types/mdast':
|
||||||
|
specifier: ^3.0.11
|
||||||
|
version: 3.0.11
|
||||||
|
'@types/unist':
|
||||||
|
specifier: ^2.0.6
|
||||||
|
version: 2.0.6
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^5.59.7
|
specifier: ^5.59.7
|
||||||
version: 5.59.7(eslint@8.41.0)(typescript@5.0.4)
|
version: 5.59.7(eslint@8.41.0)(typescript@5.0.4)
|
||||||
@@ -1338,7 +1357,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==}
|
resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 2.0.6
|
'@types/unist': 2.0.6
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/mdx@2.0.5:
|
/@types/mdx@2.0.5:
|
||||||
resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==}
|
resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==}
|
||||||
@@ -1368,7 +1386,6 @@ packages:
|
|||||||
|
|
||||||
/@types/unist@2.0.6:
|
/@types/unist@2.0.6:
|
||||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/yargs-parser@21.0.0:
|
/@types/yargs-parser@21.0.0:
|
||||||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
||||||
@@ -4685,6 +4702,10 @@ packages:
|
|||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/moment@2.29.4:
|
||||||
|
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mri@1.2.0:
|
/mri@1.2.0:
|
||||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -5753,6 +5774,10 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
|
/reading-time@1.5.0:
|
||||||
|
resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/regenerator-runtime@0.13.11:
|
/regenerator-runtime@0.13.11:
|
||||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||||
|
|
||||||
|
|||||||
BIN
public/assets/images/cover/home-documentary.jpg
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
public/assets/images/posts/design-koi.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
public/assets/images/posts/gitweb-theme-commit.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
public/assets/images/posts/gitweb-theme-commitdiff.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
public/assets/images/posts/gitweb-theme-log.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/assets/images/posts/gitweb-theme-projects.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
public/assets/images/posts/gitweb-theme-summary.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
public/assets/images/posts/gitweb-theme-tree.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/assets/images/posts/gtd-after.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
public/assets/images/posts/gtd-before.jpg
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
public/assets/images/posts/suikoden-luta.jpg
Normal file
|
After Width: | Height: | Size: 108 KiB |
16
src/components/Bookshelf.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ComponentChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Bookshelf: FunctionalComponent<Props> = ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<article
|
||||||
|
class="grid grid-cols-[repeat(auto-fit,_minmax(150px,_1fr))] place-items-center justify-center gap-[20px] rounded-4 bg-white/50 p-10 mbe-10 mbe-13 mbs-0 mbs-0 mie-0 mis-0 dark:bg-black/80"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { aiArt, haiku, projects, sketchnotes } from '../schema';
|
import { aiArt, haiku, journal, projects, sketchnotes } from '../schema';
|
||||||
|
|
||||||
export const collections = {
|
export const collections = {
|
||||||
|
'ai-art': aiArt,
|
||||||
haiku: haiku,
|
haiku: haiku,
|
||||||
|
journal: journal,
|
||||||
projects: projects,
|
projects: projects,
|
||||||
sketchnotes: sketchnotes,
|
sketchnotes: sketchnotes,
|
||||||
'ai-art': aiArt,
|
|
||||||
};
|
};
|
||||||
|
|||||||
79
src/content/journal/2007/gtd.mdx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
title: "GTD: Getting Things Done"
|
||||||
|
slug: gtd
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2007-11-24T01:15:00+02:00
|
||||||
|
description: "I’ve been working with GTD (Getting Things Done) for 1.5 years: An Introduction to Organization and Self-Management with GTD."
|
||||||
|
tags: ["productivity", "self-improvement"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## One and a Half Years With GTD
|
||||||
|
|
||||||
|
For one and a half years I use now the principles of _GTD_ (<em>Getting Things Done</em>®), from the book by _David Allen_, to organize my tasks.
|
||||||
|
|
||||||
|
In his book _<AffiliateLink asin="0143126563" text="Getting Things Done: The Art of Stress-Free Productivity" />_, David Allen introduces an interesting system that allows you to do your tasks efficiently.
|
||||||
|
|
||||||
|
<Bookshelf>
|
||||||
|
<AmazonBook asin="0143126563" />
|
||||||
|
</Bookshelf>
|
||||||
|
|
||||||
|
In any case, I think that one _gets_ the everyday madness governed by Allen’s system.
|
||||||
|
|
||||||
|
## The GTD Basics
|
||||||
|
|
||||||
|
<Figure caption="This is what the inbox looked like before I sorted all loose ends">
|
||||||
|
<Image src="/assets/images/posts/gtd-before.jpg" alt="My desk before" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
GTD uses the concept of _contexts_, which are certain situations/places to which a task is assigned (telephone, home, care, or similar). Besides, there can be an allocation to a _project_.
|
||||||
|
|
||||||
|
Tasks are done within a context, which means you do several calls at once if you’re on the phone.
|
||||||
|
|
||||||
|
In GTD, everything unsorted that comes on the table is moved to an Inbox. These can be a variety of things, consisting of e-mails, mail, voice memos, notes, or scribbles. The Inbox will be emptied at a picked time—for example, Friday afternoon or every day at 18:00—with each task being processed, leaving nothing unprocessed in the Inbox.
|
||||||
|
|
||||||
|
Depending on the estimated effort, the tasks are either completed immediately (if the duration is about 2 minutes) or moved to another location. If the task is part of a multipart process, a project is created to which you assign the task.
|
||||||
|
|
||||||
|
Things can additionally be moved as reference material for later (like a brochure).
|
||||||
|
|
||||||
|
You might not do a task currently because you have no time or no active interest in it. It might be interesting enough to keep it. You move these types of tasks to a _Someday_ list. It can be reviewed now and then. Thus, the ideas are not lost but do not burden the head.
|
||||||
|
|
||||||
|
Tasks can be delegated to other people or planned for certain times. If you have to wait for someone else to do a task, you assign it to the context of _Waiting_.
|
||||||
|
|
||||||
|
## GTD in Everyday Life
|
||||||
|
|
||||||
|
<Figure caption="This is what the inbox looked like after sorting all loose ends">
|
||||||
|
<Image src="/assets/images/posts/gtd-after.jpg" alt="My desk afterward" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
GTD may look complicated or awkward, but it helps immensely to prevent keeping pondering.
|
||||||
|
|
||||||
|
After a short time of adjustment, I got used to this way of working. I quickly took over the habit of writing every thought and classifying them by the GTD principles. I never forget important things again, and even small ideas do not disappear from my head.
|
||||||
|
|
||||||
|
Ideally, you have certain **work tools** that can vary depending on the person and circumstances. I use a combination of web applications, text files, [Moleskine®](http://moleskine.com) notebook, and post-its® in different places (on the bedside table).
|
||||||
|
|
||||||
|
For computer professionals, numerous systems and programs allow GTD digital. Thus, the right work tool should be found for everyone. Whole sites and weblogs deal with GTD (for example [lifehack.org](https://www.lifehack.org/), [Lifehacker](https://lifehacker.com/) or [43 Folders](http://www.43folders.com/)).
|
||||||
|
|
||||||
|
## The Right GTD Solution?
|
||||||
|
|
||||||
|
Since I met GTD for the first time, I’m looking for and testing alternative solutions for Allen’s system.
|
||||||
|
|
||||||
|
The perfect system in the daily implementation doesn’t exist for me, with **all** solutions you have to compromise. When a neural interface has been developed, in which one can feed their thoughts instantly in text form and can retrieve them directly and anywhere on the retina, I will be satisfied.
|
||||||
|
|
||||||
|
The GTD solutions I’ve seen have been either too simple or too complex for me.
|
||||||
|
|
||||||
|
Simple systems, such as pure text, did not work for me. Certain things always remained outside. I’ve been testing an interesting candidate with [TaskPaper](http://www.hogbaysoftware.com/products/taskpaper) over the last few weeks, which did not allow me to schedule appointments and so was not good enough for the long-term test. Let's see how the software evolves.
|
||||||
|
|
||||||
|
The **complex systems**, which allowed various lists, keywords, various data, and mappings, were too time-consuming.
|
||||||
|
|
||||||
|
Key features for me are:
|
||||||
|
|
||||||
|
1. **Location independence**, since I am an employee, I want to capture my thoughts from different places.
|
||||||
|
2. **System independence** is not relevant for me, but I aim to avoid depending on certain operating systems.
|
||||||
|
3. Assigning **Appointments** is for me a separation between a diary and _Next Actions_ and is out of the question.
|
||||||
|
4. **Fast and easy** is important, ideally to create tasks without a mouse.
|
||||||
|
|
||||||
|
At the same time, I've sometimes gone double-tracked to test a new system, but I use my primary tool.
|
||||||
|
|
||||||
|
## Update
|
||||||
|
|
||||||
|
After its release in 2009, I started using [Things](https://culturedcode.com/things/) by Cultured Code. After using it for a few years, updates became scarce, and the next version was late for years. I tried meanwhile alternative solutions, but some months after the release of **Things 3** I switched back, because of its easy-to-use interface and instant synchronization speed.
|
||||||
24
src/content/journal/2007/japanese-colors.mdx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
title: Colors of Japan
|
||||||
|
slug: japanese-colors
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2007-12-08T21:05:00+02:00
|
||||||
|
description: Traditional, Japanese colors as a color palette for Photoshop and Illustrator to download (FREE).
|
||||||
|
tags: ["design", "download"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color Palette for Graphic Software
|
||||||
|
|
||||||
|
During a visit to the art exhibition _Japan and the West_ in the [Art Museum Wolfsburg](https://www.kunstmuseum-wolfsburg.de/), I was able to get my hands on a wonderful book about the traditional, Japanese colors.
|
||||||
|
|
||||||
|
In the museum shop, I bought the book _<AffiliateLink asin="4894445786" text="The Traditional Colors of Japan" />_ which is in Japanese. In addition to a full-color palette of 250 colors, it contains an exact indication of RGB, CMYK, and other information.
|
||||||
|
|
||||||
|
<Bookshelf>
|
||||||
|
<AmazonBook asin="4894445786" />
|
||||||
|
</Bookshelf>
|
||||||
|
|
||||||
|
Each page of the book shows three colors that are always juxtaposed with one or more stunning photos. The photos show the traditional use of colors in kimonos, samurai armor, monk clothing, or nature.
|
||||||
|
|
||||||
|
I took the time to create the RGB palette with the correct color names as an Adobe Exchange file (ASE). This color palette can be used in Photoshop or Illustrator.
|
||||||
|
|
||||||
|
<MoreLink href="/traditional-colors-of-japan/" text="See Traditional Colors of Japan" />
|
||||||
67
src/content/journal/2007/koi-design.mdx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: Koi Design
|
||||||
|
slug: koi-design
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2007-06-02T02:00:00+02:00
|
||||||
|
description: Irezumi (Japanese tattooing) is an inspiration for my website and the origin of my design.
|
||||||
|
tags: ["design"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Inspiration and Idea For My Header
|
||||||
|
|
||||||
|
The idea for the design of a previous version of this website has been buzzing around in my head for a while. As an inspiration, I used the art of Japanese tattoo – Irezumi.
|
||||||
|
|
||||||
|
## Irezumi – The Japanese Tattoo
|
||||||
|
|
||||||
|
Tattoos are an art that is transient in the truest sense of the word since with the wearer the artwork disappears as soon as they die. But this fits in well with the concept of the _flowing world_, a concept of transience in Buddhism. In the symbol of the samurai, the cherry blossom, one can see the transience of being after a short duration of a perfect life.
|
||||||
|
|
||||||
|
These works of art are painful (dozens of bamboo needles are [stung several times a second](https://youtu.be/NddXHY2QUV0)), tedious (from a few months to several years), and expensive (starting at €20,000). That is the reason I like to look at them, but will never wear one myself.
|
||||||
|
|
||||||
|
One of the best living artists of the Irezumi is Horiyoshi III, whose works can be seen in many illustrated books: <AffiliateLink asin="9074822452" text="Tattoos from the Floating World: Ukiyo-e Motif’s in Japanese Tattoo" /> and <AffiliateLink asin="0764312014" text="Bushido: Legacies of the Japanese Tattoo" />.
|
||||||
|
|
||||||
|
<Bookshelf>
|
||||||
|
<AmazonBook asin="9074822452" />
|
||||||
|
<AmazonBook asin="0764312014" />
|
||||||
|
</Bookshelf>
|
||||||
|
|
||||||
|
Irezumi does not at random tattoo things on the body, the images have a profound meaning to the wearer and require expertise in religion, history, and myths from China and Japan. That is the reason bad copies and pseudo-Japanese tattoos are offered in Western tattoo studios. These tattooists lack this background knowledge.
|
||||||
|
|
||||||
|
## Yakuza
|
||||||
|
|
||||||
|
The Japanese tattoo got famous through their most significant carriers – the members of the Japanese criminal organization [Yakuza](https://en.wikipedia.org/wiki/Yakuza) – but today Irezumi is worn by businessmen and even Housewives.
|
||||||
|
|
||||||
|
The links to the Japanese art of [ukiyo-e](https://en.wikipedia.org/wiki/Ukiyo-e) (woodcut) are fluid and the motives are the same.
|
||||||
|
|
||||||
|
## Motives
|
||||||
|
|
||||||
|
In addition to gods, mythical creatures, and demons, the most important source of motifs is the ancient Chinese novella _[Shuǐhǔ Zhuàn](https://en.wikipedia.org/wiki/Water_Margin)_ (Water Margin), known in Japan as _Suikoden_. It belongs to one of the four classical books of Chinese literature. The German translation of this entertaining book is called _<AffiliateLink asin="3458318917" text="Die Räuber vom Liang Schan Moor" />_.
|
||||||
|
|
||||||
|
## Water Margin
|
||||||
|
|
||||||
|
<Figure
|
||||||
|
caption="Motif from Suikoden by Kuniyoshi: Captain Lu-Ta, the flowery monk, smashes a tree with a blow to impress a gang of good-for-nothings."
|
||||||
|
size="wide"
|
||||||
|
>
|
||||||
|
<Image src="/assets/images/posts/suikoden-luta.jpg" alt="Woodblock print of a Chinese Monk" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
In short, it is about a band of robbers of 108 heroic men and women. Each of whom is forced into lawless life by adverse circumstances, and entrenching themselves on a fortified island in Liang-Shan marsh, where they go on a rampant raid for years. They fight against corrupt officials of the emperor and numerous villains. The story is true in parts and should have taken place in the Song Dynasty.
|
||||||
|
|
||||||
|
The adventure is available in paperback format and entertaining – even for children – although one or the other side is more violent than the regular children’s book.
|
||||||
|
|
||||||
|
## Meaning of the Motif
|
||||||
|
|
||||||
|
The motif I chose for my design shows a koi (carp) trying to swim up the heavy rapids of Longmen Falls.
|
||||||
|
|
||||||
|
Legend has it that a koi, who manages to swim up the magical waterfalls, transforms into a dragon. After another 500 years, he turns into a horned dragon and after 1000 years into a winged dragon. Thus, the next design should show a dragon.
|
||||||
|
|
||||||
|
<Figure
|
||||||
|
caption="Koi floating up the Longmen Waterfalls. It contains typical elements such as leaves, flowers, and wave crests."
|
||||||
|
size="fullsize"
|
||||||
|
>
|
||||||
|
<Image src="/assets/images/posts/design-koi.png" format="avif" alt="Design: Digital Irezumi" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
The hardest part of my design was how much tattooing to see on the page. While the Japanese tattoo lives on the surface, leaving nothing to feet, hands, and a small front area, a large area would have made the page restless and distracted from the content. To make matters worse, there is no end to a body tattoo. But on the internet, your space is limited by the edges of the browser.
|
||||||
|
|
||||||
|
Nevertheless, I hope that I have managed to capture the appearance of an Irezumi digitally.
|
||||||
88
src/content/journal/2009/git.mdx
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
title: Git
|
||||||
|
slug: git
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2009-02-10T20:00:00+02:00
|
||||||
|
description: An extensive collection of links to tutorials, tutorials, screencasts, and documentation on Git.
|
||||||
|
tags: ["code"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Introduction to Git
|
||||||
|
|
||||||
|
I have been using the Git version control system for almost one and a half years and am thrilled every day. Even at my employer, switching from Subversion to Git will soon happen.
|
||||||
|
|
||||||
|
At home, everything is Git repositories on my hard drive, and I cannot imagine working without Git anymore. Git has improved a lot over the last year and a lot of additional software, documentation, and films have been released for Git.
|
||||||
|
|
||||||
|
I replace the now obsolete post of 2007 with a large list of helpful links to Git:
|
||||||
|
|
||||||
|
## Official Website
|
||||||
|
|
||||||
|
- [Git – Fast Version Control System](https://git-scm.com/)
|
||||||
|
|
||||||
|
## Tutorials and Documentations
|
||||||
|
|
||||||
|
- [The Git Community Book](https://git-scm.com/book) – The community book, available online and as a PDF
|
||||||
|
|
||||||
|
### Short Instructions
|
||||||
|
|
||||||
|
- [tryGit](http://try.github.io/levels/1/challenges/1) – Learn Git interactive in the browser
|
||||||
|
- [Git Immersion](http://gitimmersion.com/) – Beautifully designed Guided Tour through the basics of Git
|
||||||
|
- [git – the simple guide](http://rogerdudler.github.io/git-guide/) – Git in a nutshell (on a long page)
|
||||||
|
- [Official Git Tutorial](https://www.kernel.org/pub/software/scm/git/docs/gittutorial.html)
|
||||||
|
- [SVN Crash Course](https://git-scm.com/course/svn.html) – A crash course for people who already know SVN
|
||||||
|
- [Effectively Using Git With Subversion](https://www.viget.com/articles/effectively-using-git-with-subversion) – A good introduction to how to use Subversion (SVN) with Git
|
||||||
|
- [Git Ready](http://gitready.com/) – Short git tips for beginners, advanced, and professionals
|
||||||
|
- [Sei (k)ein Blödmann und nimm Git: Einführung in Versionskontrolle mit Git](https://www.slideshare.net/kogakure/sei-kein-bldmann-und-nimm-git-1830449/) – my German presentation about Git
|
||||||
|
|
||||||
|
### Instructions with More Detail
|
||||||
|
|
||||||
|
- [Intro to Distributed Version Control (Illustrated)](https://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/) – Detailed, illustrated explanation of distributive version control
|
||||||
|
- [Git for Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) – A brief introduction to the technical details in Git
|
||||||
|
- [Git User’s Manual](https://www.kernel.org/pub/software/scm/git/docs/user-manual.html) – The Official User Guide
|
||||||
|
- [Git Magic](http://www-cs-students.stanford.edu/~blynn/gitmagic/) – An alternative book
|
||||||
|
- [The GitHub Guides](https://help.github.com/) – GitHub tips and tutorials
|
||||||
|
- [An Illustrated Guide to Git on Windows](http://nathanj.github.io/gitguide/) – Step-by-step guide for Windows users
|
||||||
|
- [Vss2git](Https://Github.Com/Trevorr/Vss2git) – A Windows GUI That Exports an Existing Microsoft Visual Sourcesafe 6.0 (VSS) Repository to a New Git Repository.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Reference Manual](https://www.kernel.org/pub/software/scm/git/docs/) – Detailed reference of all commands
|
||||||
|
- [Git Cheat Sheet](http://zrusin.blogspot.com/2007/09/git-cheat-sheet.html) – A useful cheat sheet
|
||||||
|
|
||||||
|
## Videos and Screencasts
|
||||||
|
|
||||||
|
- [Official Git Screencasts](https://git-scm.com/videos)
|
||||||
|
- [Google Tech Talk: Linus Torvalds on git](https://youtu.be/4XpnKHJAok8) – Linus Torvalds presents Git at Google
|
||||||
|
- [Google Tech Talk: Git](https://youtu.be/8dhZ9BXQgc4) – Randal Schwartz introduces Git for an hour
|
||||||
|
- [Git the basics](http://excess.org/article/2008/07/ogre-git-tutorial/) – Bart Trojanowski introduces Git (2 parts)
|
||||||
|
|
||||||
|
## Git Hosting
|
||||||
|
|
||||||
|
- [GitHub](https://github.com/)
|
||||||
|
- [Bitbucket](https://bitbucket.org/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Software
|
||||||
|
|
||||||
|
### MacOS
|
||||||
|
|
||||||
|
- [Gity](https://github.com/beheadedmyway/gity) – Git-GUI with many features in the Snow Leopard style (now under Open Source!)
|
||||||
|
- [GitX](http://gitx.frim.nl/) – Chic Git GUI for Mac OS X.
|
||||||
|
- [ProjectPlus](http://ciaranwal.sh/2008/08/05/textmate-plug-in-projectplus) – TextMate plug-in, the Git, Mercurial, Bazaar, and SVN status flags supported
|
||||||
|
- [Git TextMate bundle](https://github.com/jcf/git-tmbundle) – TextMate bundle
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
- [Git for Windows](https://gitforwindows.org/) – A Windows Git GUI
|
||||||
|
- [Git Extensions](http://gitextensions.github.io/) – A sleek Windows Git GUI, with 5 screencasts to use
|
||||||
|
- [TortoiseGit](https://tortoisegit.org) – Git as a Windows Explorer shell extension
|
||||||
|
- [SmartGit](https://www.syntevo.com/smartgit/) – Commercial solution for Windows, Mac OS X, and Linux
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
There’s no reason now **not** switch to Git, and any ridiculous argument against Git can be casually refuted. Although there are a lot of subversion repositories, even _this_ can be cloned without problems thanks to `git-svn` (which is installed with Git).
|
||||||
|
|
||||||
|
Subversion and Git (Mercurial, Bazaar, …) cannot be compared because their approach is different. With Git, you can work in the same way (central repository) as with Subversion. But you can work distributed and use the many fantastic possibilities of Git (local branches, offline work, nearly no server load, small file size, …).
|
||||||
|
|
||||||
|
If Subversion is used in your company, and it does not work to introduce Git (despite Git’s clear, business benefits), then use git-svn for a transitional period (people will not even know). Although not all options are available from Git, the work is at least easier.
|
||||||
44
src/content/journal/2009/gitweb-theme.mdx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
title: GitWeb Theme
|
||||||
|
slug: gitweb-theme
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2009-02-19T20:00:00+02:00
|
||||||
|
description: My popular theme for GitWeb to download for free. Now GitWeb looks more similar to GitHub and is not ugly anymore.
|
||||||
|
tags: ["download"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## GitHub Style for GitWeb
|
||||||
|
|
||||||
|
The standard theme of GitWeb is not appealing and was designed for functionality.
|
||||||
|
|
||||||
|
I could not stand it anymore. I have created an alternative, which I based on the design of GitHub.
|
||||||
|
|
||||||
|
The exact installation instructions are included in the package on GitHub.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
<Figure caption="Project View">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-projects.png" alt="Project View" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<Figure caption="Summary">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-summary.png" alt="Summary" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<Figure caption="Commit">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-commit.png" alt="Commit" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<Figure caption="Commit DIFF">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-commitdiff.png" alt="Commit DIFF" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<Figure caption="Log">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-log.png" alt="Log" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<Figure caption="Tree View">
|
||||||
|
<Image src="/assets/images/posts/gitweb-theme-tree.png" alt="Tree View" />
|
||||||
|
</Figure>
|
||||||
|
|
||||||
|
<MoreLink href="https://github.com/kogakure/gitweb-theme/" text="GitWeb Theme on GitHub" />
|
||||||
33
src/content/journal/2009/home-documentary.mdx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
title: HOME
|
||||||
|
slug: home-documentary
|
||||||
|
author: Stefan Imhoff
|
||||||
|
date: 2009-06-15T17:23:00+02:00
|
||||||
|
description: "Recommended Film: View the nature documentation HOME by Yann Arthus-Bertrand for FREE. Beautiful aerial photographs of the world. The creation of the earth, life, destruction by man and hope and ways out."
|
||||||
|
cover: /assets/images/cover/home-documentary.jpg
|
||||||
|
tags: ["film"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stunning Documentary About Our Earth
|
||||||
|
|
||||||
|
On June 5, 2009, Yann Arthus-Bertrand’s documentary film [HOME](https://youtu.be/jqxENMKaeCU) started simultaneously and free of charge in all countries, on the internet, on television, and in cinemas, where the film was even made available to the cinemas for free. In addition, the film is available on DVD, and part of the sale price will be donated to the organization _Good Planet_.
|
||||||
|
|
||||||
|
With a budget of approximately $10-15 million, sponsored by [EuropaCorp](http://www.europacorp.com/) and PPR, the director wanted to create a moving film about our planet, in which he consistently succeeded.
|
||||||
|
|
||||||
|
<Pullquote>No time for pessimism.</Pullquote>
|
||||||
|
|
||||||
|
The film has a playing time of 1 hour and 33 minutes and is roughly divided into three parts:
|
||||||
|
|
||||||
|
1. The origin of the earth, life, and species
|
||||||
|
2. The destruction and traces of Homo Sapiens
|
||||||
|
3. Hope and ways out
|
||||||
|
|
||||||
|
The shots are shot in stunning (or terrifying) landscapes throughout the air and are commented on by a narrator. In addition, beautiful music was composed by Armand Amar. The composer has used many musicians from different nations, including the wonderful singer Gombodorj Byambajarga, the Mongolian singer Enkhajargal Dandarvaanchig, drummers from Shanghai, and the Budapest Symphony Orchestra from Hungary.
|
||||||
|
|
||||||
|
<Pullquote>Dubai has endless sun, but no solar panels.</Pullquote>
|
||||||
|
|
||||||
|
The film is designed to get viewers to write about it, make their governments turn around, and raise awareness of the topic. Even compared to other films on this topic, _HOME_ is the most impressive documentary I’ve seen.
|
||||||
|
|
||||||
|
The film provides facts and frightening images that will scare even educated and well-informed people. It has on the other side images of stunning beauty, which give reason to preserve our earth.
|
||||||
|
|
||||||
|
You can watch the movie in HD on [YouTube](https://youtu.be/jqxENMKaeCU).
|
||||||
139
src/pages/[...slug].astro
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
---
|
||||||
|
import cx from 'classnames';
|
||||||
|
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
|
import { sortByDate } from '../utils';
|
||||||
|
import { dateToFormat, dateToISO, wordCount } from '../utils';
|
||||||
|
|
||||||
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
|
import Pagination from '../components/Pagination.astro';
|
||||||
|
import Picture from '../components/Picture.astro';
|
||||||
|
import { TextLink } from '../components';
|
||||||
|
|
||||||
|
import { mapping } from '../mdx-components';
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const journalEntries = await getCollection('journal');
|
||||||
|
const numberOfPages = journalEntries.length;
|
||||||
|
journalEntries.sort(sortByDate).reverse();
|
||||||
|
|
||||||
|
return journalEntries.map((entry, index) => ({
|
||||||
|
params: { slug: entry.slug },
|
||||||
|
props: {
|
||||||
|
entry,
|
||||||
|
next:
|
||||||
|
index + 1 === numberOfPages
|
||||||
|
? { slug: null, data: null }
|
||||||
|
: journalEntries[index + 1],
|
||||||
|
prev: index === 0 ? {} : journalEntries[index - 1],
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { entry, prev, next } = Astro.props;
|
||||||
|
const {
|
||||||
|
Content,
|
||||||
|
remarkPluginFrontmatter: { minutesRead },
|
||||||
|
} = await entry.render();
|
||||||
|
|
||||||
|
const title = entry.data.title;
|
||||||
|
const description = '…';
|
||||||
|
---
|
||||||
|
|
||||||
|
<GridLayout title={title} description={description} grid="fullsize" innerGrid backLink="/journal/">
|
||||||
|
<PageTitle slot="title" class="!text-6">
|
||||||
|
{entry.data.title}
|
||||||
|
</PageTitle>
|
||||||
|
|
||||||
|
{
|
||||||
|
entry.data.cover && (
|
||||||
|
<Picture
|
||||||
|
alt={entry.data.title}
|
||||||
|
aspect={1.6}
|
||||||
|
breakpoints={[300, 500, 700, 1000, 1300, 1500, 1800, 2000]}
|
||||||
|
class="col-span-full h-auto !mbe-0 xl:col-start-1 xl:col-end-14 3xl:col-end-13 [&_img]:!w-full [&_img]:!max-w-none [&_picture]:!w-full [&_picture]:!max-w-none"
|
||||||
|
format={['webp', 'avif']}
|
||||||
|
src={entry.data.cover}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
<aside
|
||||||
|
class={cx(
|
||||||
|
'col-start-2 col-end-18 md:col-start-5 md:col-end-15 xl:col-start-15 xl:col-end-18 xl:row-start-2 3xl:col-start-14 3xl:col-end-18',
|
||||||
|
{ 'row-start-3': entry.data.cover }
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div class="leading-none mbe-6">
|
||||||
|
<em>By</em>
|
||||||
|
<TextLink href="/about/">{entry.data.author}</TextLink>
|
||||||
|
</div>
|
||||||
|
<div class="leading-tight">
|
||||||
|
<time datetime={dateToISO(entry.data.date)}>{dateToFormat(entry.data.date)}</time>
|
||||||
|
</div>
|
||||||
|
<div class="leading-none">
|
||||||
|
{wordCount(entry.body)}
|
||||||
|
<span class="italic">words</span> • {minutesRead}
|
||||||
|
<span class="italic">read</span>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
<div
|
||||||
|
class="journal-post col-start-2 col-end-18 md:col-start-5 md:col-end-15 xl:col-start-6 xl:col-end-14 3xl:col-start-7 3xl:col-end-13"
|
||||||
|
>
|
||||||
|
<Content components={mapping} />
|
||||||
|
{
|
||||||
|
entry.data.updated && (
|
||||||
|
<footer class="mbs-10">
|
||||||
|
<b>Last Updated:</b>
|
||||||
|
<time datetime={dateToISO(entry.data.updated)}>
|
||||||
|
{dateToFormat(entry.data.updated)}
|
||||||
|
</time>
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Pagination
|
||||||
|
nextText={'Next'}
|
||||||
|
nextUrl={next.slug && next.slug}
|
||||||
|
previousText={'Next'}
|
||||||
|
previousUrl={prev.slug && prev.slug}
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
.journal-post {
|
||||||
|
& > h2 {
|
||||||
|
@apply text-4 mbe-9 mbs-14;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > h3,
|
||||||
|
& > h4,
|
||||||
|
& > h5,
|
||||||
|
& > h6 {
|
||||||
|
@apply text-3 !mbs-14;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > h2:first-of-type,
|
||||||
|
& > h3:first-of-type,
|
||||||
|
& > h4:first-of-type,
|
||||||
|
& > h5:first-of-type,
|
||||||
|
& > h6:first-of-type {
|
||||||
|
@apply mbs-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > *:first-child {
|
||||||
|
@apply mbs-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > pre {
|
||||||
|
@apply md:mie-[calc(5.55vw_*_-1)] md:mis-[calc(5.55vw_*_-1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
& > figure {
|
||||||
|
@apply md:mie-[calc(5.55vw_*_-1_*_3)] md:mis-[calc(5.55vw_*_-1_*_3)] xl:mie-[calc(5.55vw_*_-1_*_2)] xl:mis-[calc(5.55vw_*_-1_*_2)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -3,7 +3,7 @@ import cx from 'classnames';
|
|||||||
|
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../utils';
|
||||||
|
|
||||||
import GridLayout from '../layouts/GridLayout.astro';
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
import PageTitle from '../components/PageTitle.astro';
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
@@ -24,12 +24,12 @@ const description = '…';
|
|||||||
<PageTitle grid="wide" innerGrid>AI Art</PageTitle>
|
<PageTitle grid="wide" innerGrid>AI Art</PageTitle>
|
||||||
|
|
||||||
<article
|
<article
|
||||||
class="col-start-1 col-end-17 grid md:col-start-4 md:col-end-12 xl:col-start-5 xl:col-end-11"
|
class="col-start-1 col-end-18 grid md:col-start-4 md:col-end-12 xl:col-start-5 xl:col-end-11"
|
||||||
>
|
>
|
||||||
<Intro components={mapping} />
|
<Intro components={mapping} />
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<nav class="md:col-start-1 md:col-end-16" aria-label="AI Art">
|
<nav class="col-start-1 col-end-18 md:col-start-1 md:col-end-16" aria-label="AI Art">
|
||||||
<ol
|
<ol
|
||||||
class="gap-[max(25px,_2vw)] md:grid md:grid-flow-row-dense md:auto-rows-gallery md:grid-cols-gallery md:grid-rows-gallery"
|
class="gap-[max(25px,_2vw)] md:grid md:grid-flow-row-dense md:auto-rows-gallery md:grid-cols-gallery md:grid-rows-gallery"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../../utils';
|
||||||
|
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import PageHeader from '../../components/PageHeader.astro';
|
import PageHeader from '../../components/PageHeader.astro';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortByDate } from '../utils/sort-by-date';
|
import { sortByDate } from '../utils';
|
||||||
|
|
||||||
import GridLayout from '../layouts/GridLayout.astro';
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
import PageTitle from '../components/PageTitle.astro';
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortByDate } from '../../utils/sort-by-date';
|
import { sortByDate } from '../../utils';
|
||||||
|
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import PageHeader from '../../components/PageHeader.astro';
|
import PageHeader from '../../components/PageHeader.astro';
|
||||||
|
|||||||
42
src/pages/journal.astro
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
|
import { sortBySortKey } from '../utils';
|
||||||
|
|
||||||
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
|
import { Content as Intro } from '../text/journal/intro.mdx';
|
||||||
|
import { Link } from '../components';
|
||||||
|
|
||||||
|
import { mapping } from '../mdx-components';
|
||||||
|
|
||||||
|
const allJournal = await getCollection('journal');
|
||||||
|
allJournal.sort(sortBySortKey);
|
||||||
|
|
||||||
|
const title = 'Journal';
|
||||||
|
const description = '…';
|
||||||
|
---
|
||||||
|
|
||||||
|
<GridLayout title={title} description={description} grid="wide" class="grid" innerGrid>
|
||||||
|
<PageTitle grid="wide" innerGrid>Journal</PageTitle>
|
||||||
|
|
||||||
|
<article
|
||||||
|
class="col-start-1 col-end-18 grid md:col-start-4 md:col-end-12 xl:col-start-5 xl:col-end-11"
|
||||||
|
>
|
||||||
|
<Intro components={mapping} />
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<nav class="md:col-start-1 md:col-end-16" aria-label="Journal">
|
||||||
|
<ol>
|
||||||
|
{
|
||||||
|
allJournal.map(({ slug, data }) => (
|
||||||
|
<li>
|
||||||
|
<Link title={data.title} href={`/${slug}/`}>
|
||||||
|
{data.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</GridLayout>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../utils';
|
||||||
|
|
||||||
import GridLayout from '../layouts/GridLayout.astro';
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
import PageTitle from '../components/PageTitle.astro';
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../../utils';
|
||||||
|
|
||||||
import GridLayout from '../../layouts/GridLayout.astro';
|
import GridLayout from '../../layouts/GridLayout.astro';
|
||||||
import PageTitle from '../../components/PageTitle.astro';
|
import PageTitle from '../../components/PageTitle.astro';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import cx from 'classnames';
|
|||||||
|
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../utils';
|
||||||
|
|
||||||
import GridLayout from '../layouts/GridLayout.astro';
|
import GridLayout from '../layouts/GridLayout.astro';
|
||||||
import PageTitle from '../components/PageTitle.astro';
|
import PageTitle from '../components/PageTitle.astro';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { sortBySortKey } from '../../utils/sort-by-sortkey';
|
import { sortBySortKey } from '../../utils';
|
||||||
|
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import PageHeader from '../../components/PageHeader.astro';
|
import PageHeader from '../../components/PageHeader.astro';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './ai-art';
|
export * from './ai-art';
|
||||||
export * from './haiku';
|
export * from './haiku';
|
||||||
|
export * from './journal';
|
||||||
export * from './projects';
|
export * from './projects';
|
||||||
export * from './sketchnotes';
|
export * from './sketchnotes';
|
||||||
|
|||||||
23
src/schema/journal.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { defineCollection, z } from 'astro:content';
|
||||||
|
|
||||||
|
export const journal = defineCollection({
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
author: z.string().default('Stefan Imhoff'),
|
||||||
|
date: z.date(),
|
||||||
|
updated: z.date().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
cover: z.string().optional(),
|
||||||
|
tags: z.array(
|
||||||
|
z.enum([
|
||||||
|
'code',
|
||||||
|
'design',
|
||||||
|
'download',
|
||||||
|
'film',
|
||||||
|
'productivity',
|
||||||
|
'self-improvement',
|
||||||
|
'tip',
|
||||||
|
])
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
});
|
||||||
1
src/text/journal/intro.mdx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Writing is a passion for me. I’ve written a huge collection of essays about [Ninja & Ninjutsu](https://www.kogakure.de/) that I later converted into a book. The online publishing platform <cite>Medium</cite> selected [one of my essays](/attention/) as a recommendation of the day.
|
||||||
9
src/utils/date.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
export const dateToFormat = (date: Date, format = 'MMMM Do, YYYY') => {
|
||||||
|
return moment(date).format(format);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const dateToISO = (date: Date) => {
|
||||||
|
return moment(date).format();
|
||||||
|
};
|
||||||
5
src/utils/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from './date';
|
||||||
|
export * from './remark-reading-time';
|
||||||
|
export * from './sort-by-date';
|
||||||
|
export * from './sort-by-sortkey';
|
||||||
|
export * from './word-count';
|
||||||
13
src/utils/remark-reading-time.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { toString } from 'mdast-util-to-string';
|
||||||
|
import getReadingTime from 'reading-time';
|
||||||
|
|
||||||
|
import type { Node } from 'unist';
|
||||||
|
|
||||||
|
export const remarkReadingTime = () => {
|
||||||
|
return function (tree: Node, { data }: { data: any }) {
|
||||||
|
const textOnPage = toString(tree);
|
||||||
|
const readingTime = getReadingTime(textOnPage);
|
||||||
|
|
||||||
|
data.astro.frontmatter.minutesRead = readingTime.text;
|
||||||
|
};
|
||||||
|
};
|
||||||
6
src/utils/word-count.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const wordCount = (text: string) => {
|
||||||
|
const clean = text.replace(/<\/?[^>]+(>|$)/g, '');
|
||||||
|
const numberOfWords = clean.split(/\s/g).length;
|
||||||
|
|
||||||
|
return numberOfWords;
|
||||||
|
};
|
||||||