Compare commits
6
Commits
d033523e88
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74d571c10f | ||
|
|
9bbbb80e75 | ||
|
|
f610edf22c | ||
|
|
5aa314e40e | ||
|
|
07fde286c4 | ||
|
|
d76464d4f3 |
+11
-8
@@ -1,18 +1,21 @@
|
||||
import { defineContentConfig, defineCollection, z } from '@nuxt/content'
|
||||
import { asSitemapCollection } from "@nuxtjs/sitemap/content"
|
||||
|
||||
// Lookup resolved from path: rootDir/content
|
||||
// see: https://github.com/nuxt/content/issues/3161
|
||||
|
||||
export default defineContentConfig({
|
||||
collections: {
|
||||
content: defineCollection({
|
||||
type: "page",
|
||||
source: "**/*.md",
|
||||
schema: z.object({
|
||||
date: z.date(),
|
||||
img: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
content: defineCollection(
|
||||
asSitemapCollection({
|
||||
type: "page",
|
||||
source: "**/*.md",
|
||||
schema: z.object({
|
||||
date: z.date(),
|
||||
img: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
})
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ for the presentation that I gave at Hogeschool Rotterdam.
|
||||
|
||||
Korte video waarin de meeste functionaliteit van de bank ATM wordt getoond.
|
||||
|
||||
::VideoLazy{:src="https://riyyi.com/media/bank-atm-demo.webm"}
|
||||
::VideoLazy{:src="/img/bank-atm/demo.webm"}
|
||||
::
|
||||
|
||||
## Overzicht componenten
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: "blaze lisp"
|
||||
description: "An implementation of the MAL (Make a Lisp) project."
|
||||
navigation: false
|
||||
date: "2023-03-18"
|
||||
img: "/img/mal-steps.png"
|
||||
tags:
|
||||
- C++20
|
||||
- CMake
|
||||
- Software
|
||||
---
|
||||
|
||||
<small>An implementation of the MAL (Make a Lisp) project.<br>
|
||||
Repository at
|
||||
[GitHub](https://github.com/riyyi/blaze){target="_blank"},
|
||||
[GitLab](https://gitlab.com/riyyi/blaze){target="_blank"} or
|
||||
[Gitea](https://git.riyyi.com/riyyi/blaze){target="_blank"}.
|
||||
</small>
|
||||
|
||||
After having implemented the JSON serializer for my [utility
|
||||
library](/articles/utility-library), I became interested in interpreters. The
|
||||
utility library just has the `tokenization` step of an interpreter, so my tought
|
||||
was, what's next? That's right, `parsing`.
|
||||
|
||||
Having used Emacs quite a bit, I wasn't shy of Lisp. Then, I came across the MAL
|
||||
([Make a Lisp](https://github.com/kanaka/mal){target="_blank"}) project, and
|
||||
decided to look into it. The project lays out the implementation steps of making
|
||||
a Lisp programming language in 10 or so steps and also provides you with unit
|
||||
tests that have to pass to proceed to the next step. There are also a bunch of
|
||||
reference implementations to refer to, in case you get stuck.
|
||||
|
||||
Feeling like implementing a fully interpreted language was a bit of an
|
||||
undertaking and realizing that in a Lisp `parsing` and `interpreting` is
|
||||
basically combined into one step, it seemed achievable and I decided to give the
|
||||
MAL project a go.
|
||||
|
||||
The final architechture that has to be implemented is pictured below.
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-xl-6">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
I managed to do a full implementation, including `variables`, `if` statements,
|
||||
`loops`, `functions`, `try/catch` exceptions, `lists`, `arrays`, `hash-maps` and
|
||||
even `macros`.
|
||||
|
||||
With the REPL you can try things out and play around easily.
|
||||
|
||||
|
||||
```
|
||||
./repl
|
||||
Blaze [C++]
|
||||
user>
|
||||
```
|
||||
|
||||
```elisp
|
||||
user> 123
|
||||
123
|
||||
user> (+ 1 2.5)
|
||||
3.5
|
||||
user> (- 10 (- 5 3))
|
||||
8
|
||||
user> "hello world"
|
||||
"hello world"
|
||||
user> (= 2 3)
|
||||
true
|
||||
user> (if (> 2 4) "yes" "no")
|
||||
"no"
|
||||
user> (count (list 3 6 2 9))
|
||||
4
|
||||
user> (count '(3 6 2 9)) ; list shorthand
|
||||
4
|
||||
user> (list? [2.1 nil "text"]) ; array / vector
|
||||
false
|
||||
user> {:a (+ 7 8)} ; hash-map
|
||||
{"a" 15}
|
||||
user> (def! mul (fn* [x y] (* x y))) ; defining a function
|
||||
#<user-function>(0x5f35f38815d0)
|
||||
user> (mul 4 5)
|
||||
20
|
||||
```
|
||||
|
||||
This project was really interesting and the language is quite powerful, powerful
|
||||
enough to accomplish self-hosting! This means that an interpreter (or rather,
|
||||
eval+apply) _for_ this language, can be written _in_ the language.
|
||||
|
||||
If you're curious about reading more examples, a good place is probably the
|
||||
testsuite for the project, those have a bunch of unit tests and are available
|
||||
[here](https://github.com/kanaka/mal/tree/master/impls/tests).
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: "GarbAGE (Garbage Accurate GameBoy Emulator)"
|
||||
description: "GameBoy Emulator that is not that accurate."
|
||||
navigation: false
|
||||
date: "2022-08-17"
|
||||
img: "/img/garbage.png"
|
||||
tags:
|
||||
- C++20
|
||||
- CMake
|
||||
- Software
|
||||
---
|
||||
|
||||
<small>GarbAGE (Garbage Accurate GameBoy Emulator).<br>
|
||||
Repository at
|
||||
[GitHub](https://github.com/riyyi/garbage){target="_blank"},
|
||||
[GitLab](https://gitlab.com/riyyi/garbage){target="_blank"} or
|
||||
[Gitea](https://git.riyyi.com/riyyi/garbage){target="_blank"}.
|
||||
</small>
|
||||
|
||||
This is an exploration into emulators by me and a friend of mine. The only thing
|
||||
thats really implemented are the CPU opcodes. The cool thing however, is that
|
||||
for the rendering portion of the application we are using my own
|
||||
[game engine](/articles/inferno)! No other libraries were used.
|
||||
|
||||
The simplest game to test is Dr. Mario and even that one doesnt render
|
||||
correctly, but we do get graphics that you can make out, pretty cool!
|
||||
|
||||

|
||||
|
||||
Preview video of the boot sequence and intro of the Dr. Mario game.
|
||||
|
||||
::VideoLazy{:src="/img/garbage-preview.webm"}
|
||||
::
|
||||
@@ -32,5 +32,5 @@ Preview.
|
||||
Demo showcasing translation, rotation, scaling and textures working. You can
|
||||
also fly around, which is not shown in the video.
|
||||
|
||||
::VideoLazy{:src="https://riyyi.com/media/opengl-test-demo.webm"}
|
||||
::VideoLazy{:src="/img/opengl-test-demo.webm"}
|
||||
::
|
||||
|
||||
@@ -76,5 +76,5 @@ Completed assembly.
|
||||
Domoticz is used as a controller, which completes the smart outlet project. View
|
||||
the demo below.
|
||||
|
||||
::VideoLazy{:src="https://riyyi.com/media/smart-outlet-demo.webm"}
|
||||
::VideoLazy{:src="/img/smart-outlet/demo.webm"}
|
||||
::
|
||||
|
||||
@@ -24,11 +24,128 @@ my projects and create one cohesive style.
|
||||
|
||||
## Argument parsing
|
||||
|
||||
placeholder
|
||||
This is a simple argument parsing feature, with the attempt of making it simpler
|
||||
to use than getopt. All you have to do is specify the variables you want to use,
|
||||
then add the options and arguments on the `ArgParser` object and finally call
|
||||
the `parse` function.
|
||||
|
||||
```cpp
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ruc/argparser.h"
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
bool verbose = false;
|
||||
std::vector<std::string> targets {};
|
||||
|
||||
ruc::ArgParser argParser;
|
||||
argParser.addOption(verbose, 'v', "verbose", nullptr, nullptr);
|
||||
argParser.addArgument(targets, "targets", nullptr, nullptr, ruc::ArgParser::Required::No);
|
||||
argParser.parse(argc, argv);
|
||||
|
||||
// Do some work here..
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The `nullptr`'s in the above example were going to be used for automatic help
|
||||
string generation, but that isn't implemented yet.
|
||||
|
||||
## Formatting library
|
||||
|
||||
placeholder
|
||||
This is basically a partial copy of the `fmt` library, from before that became
|
||||
part of the C++20 standard and I didn't want to use an additional dependency in
|
||||
my projects, because that is less fun!
|
||||
|
||||
The part of `fmt` that is implement is the
|
||||
"[mini-language](https://fmt.dev/11.1/syntax/#format-specification-mini-language)",
|
||||
which is a very convenient API.
|
||||
|
||||
```cpp
|
||||
#include <string>
|
||||
|
||||
#include "ruc/format/format.h"
|
||||
#include "ruc/format/print.h"
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
std::string fmt = format(
|
||||
R"(
|
||||
number {}
|
||||
string {}
|
||||
bool {}j
|
||||
double {}
|
||||
double {:.2} with 2 precision
|
||||
)", 123, "this is a string", true, 456.789, 3.14159265359);
|
||||
print("{}\n", fmt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Which results the the output.
|
||||
|
||||
```
|
||||
number 123
|
||||
string this is a string
|
||||
bool true
|
||||
double 456.789000
|
||||
double 3.14 with 2 precision
|
||||
```
|
||||
|
||||
The implementation consists of 2 major parts, the parsing of the format string
|
||||
and the `format` and `print` functions. The parsing part isn't that complex, so
|
||||
wont be discussed here. The other secion is interesting, however.
|
||||
|
||||
The functions are implemented with variadic arguments using type erasure, this
|
||||
improves both compile time and binary size significantly. What it also does, is
|
||||
allow the library to work on types that are specified by the user and are
|
||||
therefor not part of the library.
|
||||
|
||||
The formatter implements all the primitives and some of the STL types, it can be
|
||||
extended by the user. The basic use-case is to specify to just the `format`
|
||||
function, but the `parser` function can also be overwritten.
|
||||
|
||||
```cpp
|
||||
// In the header we are extending the existing formatter for vectors,
|
||||
// so we take advantage of their nice formatting automatically
|
||||
template<>
|
||||
struct ruc::format::Formatter<glm::vec4> : Formatter<std::vector<float>> {
|
||||
void format(Builder& builder, glm::vec4 value) const;
|
||||
};
|
||||
|
||||
// Then in the implementation, we implement the format functon
|
||||
void ruc::format::Formatter<glm::vec4>::format(Builder& builder, glm::vec4 value) const
|
||||
{
|
||||
return Formatter<std::vector<float>>::format(builder, { value.x, value.y, value.z, value.w });
|
||||
}
|
||||
```
|
||||
|
||||
Users can even extend formatters based on their own formats. In this example we
|
||||
are extending the vector (`glm::vec4`) formatter, so we can also print matrices
|
||||
(`glm::mat4`).
|
||||
|
||||
```cpp
|
||||
template<>
|
||||
struct ruc::format::Formatter<glm::mat4> : Formatter<glm::vec4> {
|
||||
void format(Builder& builder, glm::mat4 value) const;
|
||||
};
|
||||
|
||||
void ruc::format::Formatter<glm::mat4>::format(Builder& builder, glm::mat4 value) const
|
||||
{
|
||||
builder.putString("mat4 ");
|
||||
Formatter<glm::vec4>::format(builder, value[0]);
|
||||
builder.putString("\n ");
|
||||
Formatter<glm::vec4>::format(builder, value[1]);
|
||||
builder.putString("\n ");
|
||||
Formatter<glm::vec4>::format(builder, value[2]);
|
||||
builder.putString("\n ");
|
||||
return Formatter<glm::vec4>::format(builder, value[3]);
|
||||
}
|
||||
```
|
||||
|
||||
## JSON parsing
|
||||
|
||||
|
||||
+9
-2
@@ -15,7 +15,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
langs: [
|
||||
// https://github.com/shikijs/shiki/blob/main/packages/langs/package.json
|
||||
"c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "python", "shell", "ts", "vue", "yaml"
|
||||
"c", "cpp", "css", "elisp", "html", "js", "json", "lua", "md", "mdc", "php", "python", "shell", "ts", "vue", "yaml"
|
||||
]
|
||||
},
|
||||
toc: {
|
||||
@@ -36,7 +36,9 @@ export default defineNuxtConfig({
|
||||
public: "../public"
|
||||
},
|
||||
modules: [
|
||||
"@nuxt/content",
|
||||
"@nuxtjs/robots",
|
||||
"@nuxtjs/sitemap",
|
||||
"@nuxt/content", // NOTE: @nuxt/content after robots and sitemap
|
||||
"@nuxt/eslint",
|
||||
"@pinia/nuxt",
|
||||
"pinia-plugin-persistedstate/nuxt",
|
||||
@@ -52,6 +54,11 @@ export default defineNuxtConfig({
|
||||
secure: process.env.NODE_ENV !== "development" // only send over HTTPS
|
||||
}
|
||||
},
|
||||
routeRules: {
|
||||
// Dont add to the sitemap.xml
|
||||
"/__nuxt_content/**": { robots: false },
|
||||
},
|
||||
site: { url: "https://riyyi.com", name: "Personal Website" },
|
||||
srcDir: "src/",
|
||||
ssr: false,
|
||||
typescript: {
|
||||
|
||||
Generated
+268
-1
@@ -22,6 +22,8 @@
|
||||
"@iconify-json/fa-solid": "^1.2.1",
|
||||
"@nuxt/content": "^3.4.0",
|
||||
"@nuxt/eslint": "^1.2.0",
|
||||
"@nuxtjs/robots": "^5.2.9",
|
||||
"@nuxtjs/sitemap": "^7.2.10",
|
||||
"@types/bootstrap": "^5.2.10",
|
||||
"@vue/language-server": "^2.1.10",
|
||||
"@vue/typescript-plugin": "^2.1.10",
|
||||
@@ -1642,6 +1644,136 @@
|
||||
"vfile": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxtjs/robots": {
|
||||
"version": "5.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@nuxtjs/robots/-/robots-5.2.9.tgz",
|
||||
"integrity": "sha512-JJykE1llIByw8vqhrn4abSPyAcEFnfVOkIaD2/XLwkhNeZHzAQT2/p+ZhqwtaSMyWq8pnW1y0ei7gQYdCqOu+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "^3.16.2",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
"nuxt-site-config": "^3.1.9",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"sirv": "^3.0.1",
|
||||
"std-env": "^3.9.0",
|
||||
"ufo": "^1.5.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxtjs/robots/node_modules/@nuxt/kit": {
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
|
||||
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"c12": "^3.0.2",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"errx": "^0.1.0",
|
||||
"exsolve": "^1.0.4",
|
||||
"globby": "^14.1.0",
|
||||
"ignore": "^7.0.3",
|
||||
"jiti": "^2.4.2",
|
||||
"klona": "^2.0.6",
|
||||
"knitwork": "^1.2.0",
|
||||
"mlly": "^1.7.4",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"scule": "^1.3.0",
|
||||
"semver": "^7.7.1",
|
||||
"std-env": "^3.8.1",
|
||||
"ufo": "^1.5.4",
|
||||
"unctx": "^2.4.1",
|
||||
"unimport": "^4.1.3",
|
||||
"untyped": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxtjs/sitemap": {
|
||||
"version": "7.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@nuxtjs/sitemap/-/sitemap-7.2.10.tgz",
|
||||
"integrity": "sha512-7w1Ys2XIE/QVTJn5dbt2p/hrmDoGO9Ay1S3o6LI5M/MDRzKPvnXi5ByRUcc7Sfa3LUpLad5/w4IOQ4lyxhq9Hw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nuxt/devtools-kit": "^2.3.2",
|
||||
"@nuxt/kit": "^3.16.2",
|
||||
"chalk": "^5.4.1",
|
||||
"defu": "^6.1.4",
|
||||
"h3-compression": "^0.3.2",
|
||||
"nuxt-site-config": "^3.1.9",
|
||||
"ofetch": "^1.4.1",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"radix3": "^1.1.2",
|
||||
"semver": "^7.7.1",
|
||||
"sirv": "^3.0.1",
|
||||
"ufo": "^1.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxtjs/sitemap/node_modules/@nuxt/kit": {
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
|
||||
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"c12": "^3.0.2",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"errx": "^0.1.0",
|
||||
"exsolve": "^1.0.4",
|
||||
"globby": "^14.1.0",
|
||||
"ignore": "^7.0.3",
|
||||
"jiti": "^2.4.2",
|
||||
"klona": "^2.0.6",
|
||||
"knitwork": "^1.2.0",
|
||||
"mlly": "^1.7.4",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"scule": "^1.3.0",
|
||||
"semver": "^7.7.1",
|
||||
"std-env": "^3.8.1",
|
||||
"ufo": "^1.5.4",
|
||||
"unctx": "^2.4.1",
|
||||
"unimport": "^4.1.3",
|
||||
"untyped": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxtjs/sitemap/node_modules/chalk": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
|
||||
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-x64-gnu": {
|
||||
"version": "0.56.5",
|
||||
"cpu": [
|
||||
@@ -5873,6 +6005,19 @@
|
||||
"uncrypto": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/h3-compression": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/h3-compression/-/h3-compression-0.3.2.tgz",
|
||||
"integrity": "sha512-B+yCKyDRnO0BXSfjAP4tCXJgJwmnKp3GyH5Yh66mY9KuOCrrGQSPk/gBFG2TgH7OyB/6mvqNZ1X0XNVuy0qRsw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/codedredd"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"h3": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/h3/node_modules/cookie-es": {
|
||||
"version": "1.2.2",
|
||||
"dev": true,
|
||||
@@ -8425,6 +8570,110 @@
|
||||
"nuxt-component-meta": "bin/nuxt-component-meta.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/nuxt-site-config": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/nuxt-site-config/-/nuxt-site-config-3.1.9.tgz",
|
||||
"integrity": "sha512-YB69GX0st8drv1d5xypweseiEWeR22tfGdyVH3U4R+mpUSz8paBx48ArKC6MgV22DKItoQm51LVoapF5pl5bEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "^3.16.2",
|
||||
"nuxt-site-config-kit": "3.1.9",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"sirv": "^3.0.1",
|
||||
"site-config-stack": "3.1.9",
|
||||
"ufo": "^1.5.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/nuxt-site-config-kit": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/nuxt-site-config-kit/-/nuxt-site-config-kit-3.1.9.tgz",
|
||||
"integrity": "sha512-bcmpajYJgkNzA0jTq6CmmhKF2wHZUUKeVx/CIGI8lwWuAD81EBUZN0T4iKvVDo54g9UBrUUl8/5GhD65YBBG0A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nuxt/kit": "^3.16.2",
|
||||
"pkg-types": "^2.1.0",
|
||||
"site-config-stack": "3.1.9",
|
||||
"std-env": "^3.9.0",
|
||||
"ufo": "^1.5.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/nuxt-site-config-kit/node_modules/@nuxt/kit": {
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
|
||||
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"c12": "^3.0.2",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"errx": "^0.1.0",
|
||||
"exsolve": "^1.0.4",
|
||||
"globby": "^14.1.0",
|
||||
"ignore": "^7.0.3",
|
||||
"jiti": "^2.4.2",
|
||||
"klona": "^2.0.6",
|
||||
"knitwork": "^1.2.0",
|
||||
"mlly": "^1.7.4",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"scule": "^1.3.0",
|
||||
"semver": "^7.7.1",
|
||||
"std-env": "^3.8.1",
|
||||
"ufo": "^1.5.4",
|
||||
"unctx": "^2.4.1",
|
||||
"unimport": "^4.1.3",
|
||||
"untyped": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nuxt-site-config/node_modules/@nuxt/kit": {
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.16.2.tgz",
|
||||
"integrity": "sha512-K1SAUo2vweTfudKZzjKsZ5YJoxPLTspR5qz5+G61xtZreLpsdpDYfBseqsIAl5VFLJuszeRpWQ01jP9LfQ6Ksw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"c12": "^3.0.2",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.3",
|
||||
"errx": "^0.1.0",
|
||||
"exsolve": "^1.0.4",
|
||||
"globby": "^14.1.0",
|
||||
"ignore": "^7.0.3",
|
||||
"jiti": "^2.4.2",
|
||||
"klona": "^2.0.6",
|
||||
"knitwork": "^1.2.0",
|
||||
"mlly": "^1.7.4",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^2.1.0",
|
||||
"scule": "^1.3.0",
|
||||
"semver": "^7.7.1",
|
||||
"std-env": "^3.8.1",
|
||||
"ufo": "^1.5.4",
|
||||
"unctx": "^2.4.1",
|
||||
"unimport": "^4.1.3",
|
||||
"untyped": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nuxt/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"dev": true,
|
||||
@@ -10419,6 +10668,22 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/site-config-stack": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/site-config-stack/-/site-config-stack-3.1.9.tgz",
|
||||
"integrity": "sha512-ed53+wLi+36SGqidU+YUpl7f1OHClPLmvUJ/aYZny1dCBnXvOsuFottrMkXDIK2N5UaMED9mz8KrRZTk94ARCg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ufo": "^1.5.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3"
|
||||
}
|
||||
},
|
||||
"node_modules/skin-tone": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
@@ -10620,7 +10885,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/std-env": {
|
||||
"version": "3.8.1",
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
|
||||
"integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/streamx": {
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
"@iconify-json/fa-solid": "^1.2.1",
|
||||
"@nuxt/content": "^3.4.0",
|
||||
"@nuxt/eslint": "^1.2.0",
|
||||
"@nuxtjs/robots": "^5.2.9",
|
||||
"@nuxtjs/sitemap": "^7.2.10",
|
||||
"@types/bootstrap": "^5.2.10",
|
||||
"@vue/language-server": "^2.1.10",
|
||||
"@vue/typescript-plugin": "^2.1.10",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 405 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
|
||||
+4
-1
@@ -16,8 +16,11 @@ const store = useStateStore();
|
||||
store.applyColorMode();
|
||||
|
||||
useHead({
|
||||
link: [
|
||||
{ rel: "icon", type: "image/x-icon", href: getPublicPath("/favicon.ico") },
|
||||
],
|
||||
titleTemplate: (titleChunk: string | undefined): string | null => {
|
||||
return titleChunk ? `${titleChunk} - website-vue` : 'website-vue';
|
||||
return titleChunk ? `${titleChunk} - Rick van Vonderen` : 'Rick van Vonderen';
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Vendored
-8
@@ -8,25 +8,17 @@ export {}
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
IBi0Circle: typeof import('~icons/bi/0-circle')['default']
|
||||
IBiActivity: typeof import('~icons/bi/activity')['default']
|
||||
IFaAdjust: typeof import('~icons/fa/adjust')['default']
|
||||
IFaAngellist: typeof import('~icons/fa/angellist')['default']
|
||||
IFaCheck: typeof import('~icons/fa/check')['default']
|
||||
IFaClone: typeof import('~icons/fa/clone')['default']
|
||||
IFaCoffee: typeof import('~icons/fa/coffee')['default']
|
||||
IFaCope: typeof import('~icons/fa/cope')['default']
|
||||
IFaCopy: typeof import('~icons/fa/copy')['default']
|
||||
IFaGithub: typeof import('~icons/fa/github')['default']
|
||||
IFaGitlab: typeof import('~icons/fa/gitlab')['default']
|
||||
IFaHome: typeof import('~icons/fa/home')['default']
|
||||
IFaImage: typeof import('~icons/fa/image')['default']
|
||||
IFaLink: typeof import('~icons/fa/link')['default']
|
||||
IFaLinkedinSquare: typeof import('~icons/fa/linkedin-square')['default']
|
||||
IFaMoonO: typeof import('~icons/fa/moon-o')['default']
|
||||
IFaSolidMoon: typeof import('~icons/fa-solid/moon')['default']
|
||||
IFaSolidSun: typeof import('~icons/fa-solid/sun')['default']
|
||||
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<h2>CV</h2>
|
||||
<p>
|
||||
Download the PDF here:
|
||||
<a href="https://riyyi.com/media/cv-en-rick-van-vonderen.pdf">English</a>,
|
||||
<a href="https://riyyi.com/media/cv-rick-van-vonderen.pdf">Nederlands</a>
|
||||
<a :href="getPublicPath('/pdf/cv-en-rick-van-vonderen.pdf')" target="_blank">English</a>,
|
||||
<a :href="getPublicPath('/pdf/cv-rick-van-vonderen.pdf')" target="_blank">Nederlands</a>
|
||||
</p>
|
||||
|
||||
<object data="https://riyyi.com/media/cv-en-rick-van-vonderen.pdf" type="application/pdf"
|
||||
<object :data="getPublicPath('/pdf/cv-en-rick-van-vonderen.pdf')" type="application/pdf"
|
||||
style="width: 100%; height: calc(100vh - 280px)"></object>
|
||||
</template>
|
||||
|
||||
@@ -69,8 +69,5 @@ const { data: article } = await useAsyncData<ContentCollectionItem | null>(
|
||||
() => queryCollection("content").path("/articles/" + params.slug).first()
|
||||
);
|
||||
|
||||
useSeoMeta({
|
||||
title: article.value?.title,
|
||||
description: article.value?.description
|
||||
})
|
||||
useSeoMeta(article.value?.seo || {});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user