initial commit
Dieser Commit ist enthalten in:
Ursprung
f9763d7cc4
Commit
3e5f846e8d
24 geänderte Dateien mit 6429 neuen und 1 gelöschten Zeilen
3
.gitmodules
gevendort
Normale Datei
3
.gitmodules
gevendort
Normale Datei
|
@ -0,0 +1,3 @@
|
|||
[submodule "themes/ametrine"]
|
||||
path = themes/ametrine
|
||||
url = https://codeberg.org/daudix/ametrine.git
|
10
README.md
10
README.md
|
@ -1,2 +1,10 @@
|
|||
# home
|
||||
# xsiz.eu
|
||||
|
||||
## Credits
|
||||
|
||||
- [Zola](https://getzola.org) static site engine
|
||||
- [Duckquill](https://ametrine.daudix.one) great theme
|
||||
|
||||
## Disclaimer
|
||||
|
||||
The project itself is licensed under the [**MIT**](LICENSE) license, and the images and logos owned by [**XSIZ**](https://u42.dev) are licensed under the [**CC BY-NC 4.0**](https://creativecommons.org/licenses/by-nc/4.0/) license
|
||||
|
|
169
config.toml
Normale Datei
169
config.toml
Normale Datei
|
@ -0,0 +1,169 @@
|
|||
theme = "ametrine"
|
||||
title = "XSIZ"
|
||||
base_url = "https://xsiz.eu"
|
||||
description = "german dudes"
|
||||
|
||||
compile_sass = true
|
||||
minify_html = true
|
||||
build_search_index = true
|
||||
author = "XSIZ"
|
||||
|
||||
# Based on https://github.com/welpo/tabi
|
||||
#
|
||||
# To translate the entire theme, there must be a file with the same ISO 639-1
|
||||
# or BCP 47 language code in the "i18n" directory of your site or the Ametrine
|
||||
# theme, for example, "i18n/fr.toml" for French or "i18n/zh-Hans.toml" for
|
||||
# Simplified Chinese, otherwise the theme will be in English.
|
||||
#
|
||||
# ISO 639-1: https://localizely.com/iso-639-1-list/
|
||||
# BCP 47: https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
|
||||
default_language = "en"
|
||||
|
||||
taxonomies = [
|
||||
{ name = "tags", feed = true, paginate_by = 10 },
|
||||
{ name = "categories", feed = true },
|
||||
]
|
||||
|
||||
[markdown]
|
||||
highlight_code = true
|
||||
extra_syntaxes_and_themes = ["sublime"]
|
||||
highlight_theme = "css"
|
||||
highlight_themes_css = [
|
||||
{ theme = "monokai-pro-dark", filename = "syntax-theme-dark.css" },
|
||||
{ theme = "monokai-pro-light", filename = "syntax-theme-light.css" },
|
||||
]
|
||||
smart_punctuation = true
|
||||
bottom_footnotes = true
|
||||
|
||||
[search]
|
||||
# Accepted values are "elasticlunr_javascript" and "elasticlunr_json"
|
||||
index_format = "elasticlunr_json"
|
||||
|
||||
[extra]
|
||||
categories = [
|
||||
{ name = "Archived", description = "Posts that have been archived due to their age.", color = "purple", icon = "box-arrow-down" },
|
||||
{ name = "Featured", description = "Posts that are somewhat decently written.", color = "yellow", icon = "star" },
|
||||
{ name = "Hot", description = "Posts that did numbers compared to others.", color = "red", icon = "fire" },
|
||||
]
|
||||
|
||||
# Accent color used by Ametrine.
|
||||
#
|
||||
# Has a few modes:
|
||||
# - Use one of the predefinded colors:
|
||||
# accent_color = "<red, orange, yellow, green, blue, purple>"
|
||||
# - Use a single color for both light and dark modes:
|
||||
# accent_color = "hsl(270 50% 60%)"
|
||||
# - Use separate colors for light and dark modes
|
||||
# accent_color = ["hsl(270 50% 60%)", "hsl(27.567572 87% 67%)"]
|
||||
# While using custom colors, make sure they are in the HSL color format.
|
||||
accent_color = "hsl(26 100% 50%)"
|
||||
|
||||
# Additional CSS styles; expects them to be in the "./static/" directory.
|
||||
# If you are using Sass these will be generated there automatically.
|
||||
#
|
||||
# styles = [
|
||||
# "YOUR_STYLE.css",
|
||||
# "ALSO_YOUR_STYLE.css"
|
||||
# ]
|
||||
#
|
||||
# Additional JavaScript scripts; expects them to be in the "./static/"
|
||||
# directory.
|
||||
#
|
||||
# scripts = [
|
||||
# "YOUR_SCRIPT.js",
|
||||
# "ALSO_YOUR_SCRIPT.js"
|
||||
# ]
|
||||
|
||||
# Path to the page that is being considered "Home", e.g. for the "Go Home"
|
||||
# button on 404.
|
||||
# home_url = "@/home/index.md"
|
||||
# URL to website's source code.
|
||||
source_url = "https://code.xsiz.eu/xsiz/home"
|
||||
# URL to website's issue tracker.
|
||||
issues_url = "https://code.xsiz.eu/xsiz/home/issues"
|
||||
# Whether to show copy button on all code blocks that have the language set.
|
||||
# See https://www.getzola.org/documentation/content/syntax-highlighting/
|
||||
show_copy_button = true
|
||||
# Whether to show estimated read time in posts.
|
||||
show_reading_time = true
|
||||
# Whether to show a share button in article's quick actions.
|
||||
# Powered by https://shareopenly.org.
|
||||
show_share_button = true
|
||||
# show_focus_button = true
|
||||
show_backlinks = true
|
||||
# Custom separator used throughout the theme.
|
||||
# separator = "•"
|
||||
# Custom separator used in website's title and article metadata.
|
||||
# title_separator = "-"
|
||||
date_format = "%d.%B.%Y"
|
||||
date_format_long = "%d.%B.%Y, %R (%Z)"
|
||||
date_locale = "en_IE"
|
||||
timezone = "Europe/Berlin"
|
||||
analytics = false
|
||||
speed_insights = false
|
||||
show_comments_qr = true
|
||||
|
||||
[extra.meta]
|
||||
# Variables bellow accept either "true" or a filename.
|
||||
# Favicon can also accept an emoji instead of a filename.
|
||||
# File extension are being respected, so e.g. if favicon has .gif extension
|
||||
# it'll be treated as an animated one.
|
||||
# If set to "true" these will use the default filenames:
|
||||
# favicon = favicon.png
|
||||
# apple_touch_icon = apple-touch-icon.png
|
||||
# card = card.png
|
||||
favicon = true
|
||||
apple_touch_icon = true
|
||||
card = true
|
||||
|
||||
[extra.nav]
|
||||
# When set to true and [extra.fediverse] is defined, it will use avatar from
|
||||
# said Mastodon account, otherwise it'll fallback to apple_touch_icon specified
|
||||
# in [extra.meta] or its default value.
|
||||
# Also accepts arbitrary filenames and URLs for custom images.
|
||||
icon = true
|
||||
# Ignore the default behavior of using sidebar for navigation only when there's
|
||||
# more than 5 items (links, categories) in it.
|
||||
force_sidebar = true
|
||||
# Icon is required to be set on each link if "force_sidebar" is set to true
|
||||
# or there's more than 5 links.
|
||||
# Any icon name from https://phosphoricons.com can be used.
|
||||
links = [
|
||||
{ name = "Random 🦄", category = [
|
||||
{ url = "https://example.org", name = "Rob-boot", icon = "robot" },
|
||||
{ url = "https://example.org", name = "Eggman", icon = "egg" },
|
||||
{ url = "https://example.org", name = "Honse", icon = "horse" },
|
||||
{ url = "https://example.org", name = "Lie", icon = "cake" },
|
||||
] },
|
||||
]
|
||||
|
||||
[extra.footer]
|
||||
# Set to false to disable copyright text, or set to anything else to use it as
|
||||
# the copyright text (Markdown supported).
|
||||
# $YEAR will be replaced with current year.
|
||||
copyright = "© XSIZ $YEAR"
|
||||
show_powered_by = true
|
||||
# show_fediring = true
|
||||
show_last_updated = true
|
||||
|
||||
#[extra.fediverse]
|
||||
# Fediverse integration.
|
||||
# Used for:
|
||||
# - Commenting
|
||||
# - Custom emoji shortcode
|
||||
# - Website verification
|
||||
# - Author attribution
|
||||
#
|
||||
# Mastodon-powered commenting is based on
|
||||
# https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/
|
||||
#
|
||||
# Values can be overridden in the front-matter, e.g.
|
||||
# for multi-author blogs or guest posts.
|
||||
|
||||
#host = "wetdry.world"
|
||||
#user = "daudix"
|
||||
|
||||
[extra.debug]
|
||||
layout = false
|
||||
no_styles = false
|
||||
no_emojis = false
|
103
content/_index.md
Normale Datei
103
content/_index.md
Normale Datei
|
@ -0,0 +1,103 @@
|
|||
+++
|
||||
title = "Ametrine"
|
||||
[extra]
|
||||
no_header = true
|
||||
+++
|
||||
|
||||
<img id="logo" class="transparent drop-shadow" src="logo.svg" alt="VTuber-style Ametrine logo.">
|
||||
|
||||
<div class="buttons centered big">
|
||||
<a href="https://codeberg.org/daudix/ametrine">Repository →</a>
|
||||
</div>
|
||||
|
||||
***
|
||||
|
||||
{% alert(caution=true) %}
|
||||
Ametrine is currently in the pre-alpha state and SHOULD NOT be used in production, it is far from being ready.
|
||||
{% end %}
|
||||
|
||||
[Ametrine](https://en.wikipedia.org/wiki/Ametrine) is a "one of a kind" [Zola](https://www.getzola.org) theme made specifically for personal websites and blogs. It provides good defaults and easy configuration, while being powerful on demand. Its design is unique and made with great care and attention to details, it changes from time to time, and the development pace is rather rapid.
|
||||
|
||||
Some of Ametrine's features:
|
||||
|
||||
- Handwritten CSS (Sass); no Tailwind, React, or anything like that.
|
||||
- No essential JavaScript; pop-ups, sidebars, and such will work just fine without it.
|
||||
- Relatively lightweight, weights under 512kB.
|
||||
- Uses modern CSS.
|
||||
- Includes Monokai Pro theme for syntax highlighting out of the box.
|
||||
- Will make you regret using this theme.
|
||||
|
||||
## What Is This Again
|
||||
|
||||
This is a theme for the [Zola](https://www.getzola.org) static site generator; thingy that converts [Markdown](https://www.markdownguide.org) files (which is used by Reddit, Tumblr, Discord, any many others) into a fully functional websites. Zola cannot build websites without a set of templates and styles, and this theme is exactly that. Ametrine also provides some custom functionality that is not present in Zola, such as Mastodon-powered comments, various useful shortcodes for simplifying various tasks, and more.
|
||||
|
||||
You can learn more about Zola and its themes at <https://www.getzola.org>.
|
||||
|
||||
## Installation
|
||||
|
||||
{% alert(caution=true) %}
|
||||
Ametrine is currently in the pre-alpha state and SHOULD NOT be used in production, it is far from being ready.
|
||||
{% end %}
|
||||
|
||||
If you have Git set up in your project, add Ametrine as a submodule:
|
||||
|
||||
```bash
|
||||
git submodule init
|
||||
git submodule add https://codeberg.org/daudix/ametrine.git themes/ametrine
|
||||
```
|
||||
|
||||
{% alert(important=true) %}
|
||||
It is highly recommended to switch from the `main` branch to the latest release:
|
||||
{% end %}
|
||||
|
||||
```bash
|
||||
cd themes/ametrine
|
||||
git checkout tags/v0.1.0 # There is currently no tagged release
|
||||
```
|
||||
|
||||
Then, enable Ametrine in your `config.toml`:
|
||||
|
||||
```toml
|
||||
theme = "ametrine"
|
||||
```
|
||||
|
||||
To update Ametrine, simply switch to a new tag:
|
||||
|
||||
{% alert(important=true) %}
|
||||
Check the changelog for all versions after the one you are using; there may be breaking changes that require manual involvement.
|
||||
{% end %}
|
||||
|
||||
```bash
|
||||
git submodule update --remote --merge
|
||||
cd themes/ametrine
|
||||
git checkout tags/v0.1.0
|
||||
```
|
||||
|
||||
## Why It Looks the Way It Does
|
||||
|
||||
Personally, I'm sick of flat, sterile, dead UIs all over the place, and I've always liked skeuomorphism because it's fun, alive, and pleasant to look at. While it's not very feasible to make things look overly realistic, some edge highlights, nice shadows, and a vibrant palette make a big difference. The design system that Ametrine uses is made of slightly frosted colored acrylic, everything is rounded, but the edges are not so rounded, so the edge highlight is rather thin, you can think of it as Lego bricks, fun and nice to touch. The animations are very bouncy to raise the fun level even higher. Still, the balance between fun and not being annoying is maintained. Did I succeed with this premise? I don't know, you tell me :P
|
||||
|
||||
## To-Do
|
||||
|
||||
Right now Ametrine is not ready to be used in production and is in active development, here's a short roadmap of features that need to be added and things to be done before the initial release:
|
||||
|
||||
- [x] Make sure everything looks nice on mobile
|
||||
- [x] Add i18n support
|
||||
- [x] Ensure good compatibility with iOS 15, and perhaps lower
|
||||
- [x] Remove leftover unused code from [Duckquill](https://duckquill.daudix.one)
|
||||
- [ ] Support custom analytics scripts
|
||||
- [ ] Add some utility classes
|
||||
- [ ] Simplify and optimize some logic in the templates
|
||||
- [ ] Organize Sass files
|
||||
- [ ] Write good documentation
|
||||
- [ ] Credit all the stuff that needs to be credited
|
||||
|
||||
<style>
|
||||
#logo {
|
||||
width: min(calc(var(--container-width) / 2), 100%);
|
||||
}
|
||||
|
||||
#logo:hover {
|
||||
transform: var(--hover) rotate(-5deg);
|
||||
}
|
||||
</style>
|
1
content/logo.svg
Normale Datei
1
content/logo.svg
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
Nachher Breite: | Höhe: | Größe: 43 KiB |
BIN
static/404-static.gif
Normale Datei
BIN
static/404-static.gif
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 178 B |
BIN
static/404.gif
Normale Datei
BIN
static/404.gif
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 715 B |
BIN
static/apple-touch-icon.png
Normale Datei
BIN
static/apple-touch-icon.png
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 230 KiB |
11
static/audio.js
Normale Datei
11
static/audio.js
Normale Datei
|
@ -0,0 +1,11 @@
|
|||
var audioButton = document.querySelectorAll('.audio');
|
||||
|
||||
for (var i = 0; i < audioButton.length; i++) {
|
||||
audioButton[i].addEventListener('click', function (event) {
|
||||
playAudio(this.dataset.audio);
|
||||
});
|
||||
}
|
||||
|
||||
function playAudio(url) {
|
||||
new Audio(url).play();
|
||||
}
|
BIN
static/card.png
Normale Datei
BIN
static/card.png
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 31 KiB |
41
static/closable.js
Normale Datei
41
static/closable.js
Normale Datei
|
@ -0,0 +1,41 @@
|
|||
const closable = document.querySelectorAll("details.closable");
|
||||
|
||||
closable.forEach((detail) => {
|
||||
detail.addEventListener("toggle", () => {
|
||||
if (detail.open) setTargetDetail(detail);
|
||||
});
|
||||
});
|
||||
|
||||
function setTargetDetail(targetDetail) {
|
||||
closable.forEach((detail) => {
|
||||
if (detail !== targetDetail) {
|
||||
detail.open = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("click", function (event) {
|
||||
const isClickInsideDetail = [...closable].some((detail) =>
|
||||
detail.contains(event.target)
|
||||
);
|
||||
|
||||
if (!isClickInsideDetail) {
|
||||
closable.forEach((detail) => {
|
||||
detail.open = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const toggleNavbar = document.getElementById("toggle-navbar");
|
||||
const siteNavbar = document.getElementById("site-navbar");
|
||||
const mainContent = document.getElementById("main-content");
|
||||
|
||||
toggleNavbar.addEventListener("change", () => {
|
||||
if (toggleNavbar.checked) {
|
||||
toggleSidebar.checked = false;
|
||||
}
|
||||
});
|
||||
|
||||
mainContent.addEventListener("click", () => {
|
||||
if (toggleNavbar.checked) toggleNavbar.checked = false;
|
||||
});
|
420
static/comments.js
Normale Datei
420
static/comments.js
Normale Datei
|
@ -0,0 +1,420 @@
|
|||
// Based on https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/
|
||||
// Attachment, card, and spoiler code is from https://github.com/cassidyjames/cassidyjames.github.io/blob/99782788a7e3ba3cc52d6803010873abd1b02b9e/_includes/comments.html#L251-L296
|
||||
|
||||
let lazyAsyncImage = document.getElementById("lazy-async-image").textContent;
|
||||
let relAttributes = document.getElementById("rel-attributes").textContent;
|
||||
let dateLocale = document.getElementById("date-locale").textContent;
|
||||
let host = document.getElementById("host").textContent;
|
||||
let user = document.getElementById("user").textContent;
|
||||
let id = document.getElementById("id").textContent;
|
||||
|
||||
let articleAuthorText = document.getElementById("article-author-text").textContent;
|
||||
let loadingText = document.getElementById("loading-text").textContent;
|
||||
let noCommentsText = document.getElementById("no-comments-text").textContent;
|
||||
let reloadText = document.getElementById("reload-text").textContent;
|
||||
let sensitiveText = document.getElementById("sensitive-text").textContent;
|
||||
|
||||
document.getElementById("load-comments").addEventListener("click", loadComments);
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function emojify(input, emojis) {
|
||||
let output = input;
|
||||
|
||||
emojis.forEach((emoji) => {
|
||||
let picture = document.createElement("picture");
|
||||
|
||||
let source = document.createElement("source");
|
||||
source.setAttribute("srcset", escapeHtml(emoji.url));
|
||||
source.setAttribute("media", "(prefers-reduced-motion: no-preference)");
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.className = "emoji";
|
||||
img.setAttribute("src", escapeHtml(emoji.static_url));
|
||||
img.setAttribute("title", `:${emoji.shortcode}:`);
|
||||
img.setAttribute("width", "24");
|
||||
img.setAttribute("height", "24");
|
||||
if (lazyAsyncImage == "true") {
|
||||
img.setAttribute("decoding", "async");
|
||||
img.setAttribute("loading", "lazy");
|
||||
}
|
||||
|
||||
picture.appendChild(source);
|
||||
picture.appendChild(img);
|
||||
|
||||
output = output.replace(`:${emoji.shortcode}:`, picture.outerHTML);
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function loadComments() {
|
||||
let commentsWrapper = document.getElementById("comments-wrapper");
|
||||
commentsWrapper.innerHTML = "";
|
||||
|
||||
let loadCommentsButton = document.getElementById("load-comments");
|
||||
loadCommentsButton.innerHTML = loadingText;
|
||||
loadCommentsButton.disabled = true;
|
||||
|
||||
fetch(`https://${host}/api/v1/statuses/${id}/context`)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
let descendants = data["descendants"];
|
||||
if (
|
||||
descendants &&
|
||||
Array.isArray(descendants) &&
|
||||
descendants.length > 0
|
||||
) {
|
||||
commentsWrapper.innerHTML = "";
|
||||
|
||||
descendants.forEach(function (status) {
|
||||
console.log(descendants);
|
||||
if (status.account.display_name.length > 0) {
|
||||
status.account.display_name = escapeHtml(
|
||||
status.account.display_name
|
||||
);
|
||||
status.account.display_name = emojify(
|
||||
status.account.display_name,
|
||||
status.account.emojis
|
||||
);
|
||||
} else {
|
||||
status.account.display_name = status.account.username;
|
||||
}
|
||||
|
||||
let instance = "";
|
||||
if (status.account.acct.includes("@")) {
|
||||
instance = status.account.acct.split("@")[1];
|
||||
} else {
|
||||
instance = host;
|
||||
}
|
||||
|
||||
const isReply = status.in_reply_to_id !== id;
|
||||
|
||||
let op = false;
|
||||
if (status.account.acct == user) {
|
||||
op = true;
|
||||
}
|
||||
|
||||
status.content = emojify(status.content, status.emojis);
|
||||
|
||||
let comment = document.createElement("article");
|
||||
comment.id = `comment-${status.id}`;
|
||||
comment.className = isReply ? "comment comment-reply" : "comment";
|
||||
comment.setAttribute("itemprop", "comment");
|
||||
comment.setAttribute("itemtype", "http://schema.org/Comment");
|
||||
|
||||
let avatarSource = document.createElement("source");
|
||||
avatarSource.setAttribute(
|
||||
"srcset",
|
||||
escapeHtml(status.account.avatar)
|
||||
);
|
||||
avatarSource.setAttribute(
|
||||
"media",
|
||||
"(prefers-reduced-motion: no-preference)"
|
||||
);
|
||||
|
||||
let avatarImg = document.createElement("img");
|
||||
avatarImg.className = "avatar";
|
||||
avatarImg.setAttribute(
|
||||
"src",
|
||||
escapeHtml(status.account.avatar_static)
|
||||
);
|
||||
avatarImg.setAttribute(
|
||||
"alt",
|
||||
`@${status.account.username}@${instance} avatar`
|
||||
);
|
||||
if (lazyAsyncImage == "true") {
|
||||
avatarImg.setAttribute("decoding", "async");
|
||||
avatarImg.setAttribute("loading", "lazy");
|
||||
}
|
||||
|
||||
let avatarPicture = document.createElement("picture");
|
||||
avatarPicture.appendChild(avatarSource);
|
||||
avatarPicture.appendChild(avatarImg);
|
||||
|
||||
let avatar = document.createElement("a");
|
||||
avatar.className = "avatar-link";
|
||||
avatar.setAttribute("href", status.account.url);
|
||||
avatar.setAttribute("rel", relAttributes);
|
||||
avatar.appendChild(avatarPicture);
|
||||
comment.appendChild(avatar);
|
||||
|
||||
let display = document.createElement("a");
|
||||
display.className = "display";
|
||||
display.setAttribute("href", status.account.url);
|
||||
display.setAttribute("rel", relAttributes);
|
||||
display.setAttribute("itemprop", "author");
|
||||
display.setAttribute("itemtype", "http://schema.org/Person");
|
||||
display.innerHTML = status.account.display_name;
|
||||
|
||||
let instanceBadge = document.createElement("span");
|
||||
instanceBadge.className = "instance";
|
||||
instanceBadge.textContent = `@${status.account.username}@${instance}`;
|
||||
|
||||
let permalink = document.createElement("a");
|
||||
permalink.setAttribute("href", status.url);
|
||||
permalink.setAttribute("itemprop", "url");
|
||||
permalink.setAttribute("rel", relAttributes);
|
||||
permalink.textContent = new Date(
|
||||
status.created_at
|
||||
).toLocaleString(dateLocale, {
|
||||
dateStyle: "long",
|
||||
timeStyle: "short",
|
||||
});
|
||||
|
||||
let timestamp = document.createElement("time");
|
||||
timestamp.setAttribute("datetime", status.created_at);
|
||||
timestamp.classList.add("timestamp");
|
||||
timestamp.appendChild(permalink);
|
||||
permalink.classList.add("external");
|
||||
|
||||
let header = document.createElement("header");
|
||||
header.appendChild(display);
|
||||
header.appendChild(instanceBadge);
|
||||
header.appendChild(timestamp);
|
||||
comment.appendChild(header);
|
||||
|
||||
let main = document.createElement("main");
|
||||
main.setAttribute("itemprop", "text");
|
||||
|
||||
if (status.sensitive == true || status.spoiler_text != "") {
|
||||
let summary = document.createElement("summary");
|
||||
if (status.spoiler_text == "") {
|
||||
status.spoiler_text == sensitiveText;
|
||||
}
|
||||
summary.innerHTML = status.spoiler_text;
|
||||
|
||||
let spoiler = document.createElement("details");
|
||||
spoiler.appendChild(summary);
|
||||
spoiler.innerHTML += status.content;
|
||||
|
||||
main.appendChild(spoiler);
|
||||
} else {
|
||||
main.innerHTML = status.content;
|
||||
}
|
||||
comment.appendChild(main);
|
||||
|
||||
let attachments = status.media_attachments;
|
||||
let SUPPORTED_MEDIA = ["image", "video", "gifv", "audio"];
|
||||
let media = document.createElement("div");
|
||||
media.className = "attachments";
|
||||
if (
|
||||
attachments &&
|
||||
Array.isArray(attachments) &&
|
||||
attachments.length > 0
|
||||
) {
|
||||
attachments.forEach((attachment) => {
|
||||
if (SUPPORTED_MEDIA.includes(attachment.type)) {
|
||||
|
||||
let mediaElement;
|
||||
switch (attachment.type) {
|
||||
case "image":
|
||||
mediaElement = document.createElement("img");
|
||||
mediaElement.setAttribute("src", attachment.preview_url);
|
||||
|
||||
if (attachment.description != null) {
|
||||
mediaElement.setAttribute("title", attachment.description);
|
||||
}
|
||||
|
||||
if (lazyAsyncImage == "true") {
|
||||
mediaElement.setAttribute("decoding", "async");
|
||||
mediaElement.setAttribute("loading", "lazy");
|
||||
}
|
||||
|
||||
if (status.sensitive == true) {
|
||||
mediaElement.classList.add("spoiler");
|
||||
}
|
||||
|
||||
media.appendChild(mediaElement);
|
||||
break;
|
||||
|
||||
case "video":
|
||||
mediaElement = document.createElement("video");
|
||||
mediaElement.setAttribute("src", attachment.url);
|
||||
mediaElement.setAttribute("controls", "");
|
||||
|
||||
if (attachment.description != null) {
|
||||
mediaElement.setAttribute("title", attachment.description);
|
||||
}
|
||||
|
||||
if (status.sensitive == true) {
|
||||
mediaElement.classList.add("spoiler");
|
||||
}
|
||||
|
||||
media.appendChild(mediaElement);
|
||||
break;
|
||||
|
||||
case "gifv":
|
||||
mediaElement = document.createElement("video");
|
||||
mediaElement.setAttribute("src", attachment.url);
|
||||
mediaElement.setAttribute("autoplay", "");
|
||||
mediaElement.setAttribute("playsinline", "");
|
||||
mediaElement.setAttribute("loop", "");
|
||||
|
||||
if (attachment.description != null) {
|
||||
mediaElement.setAttribute("title", attachment.description);
|
||||
}
|
||||
|
||||
if (status.sensitive == true) {
|
||||
mediaElement.classList.add("spoiler");
|
||||
}
|
||||
|
||||
media.appendChild(mediaElement);
|
||||
break;
|
||||
|
||||
case "audio":
|
||||
mediaElement = document.createElement("audio");
|
||||
mediaElement.setAttribute("src", attachment.url);
|
||||
mediaElement.setAttribute("controls", "");
|
||||
|
||||
if (attachment.description != null) {
|
||||
mediaElement.setAttribute("title", attachment.description);
|
||||
}
|
||||
|
||||
media.appendChild(mediaElement);
|
||||
break;
|
||||
}
|
||||
|
||||
let mediaLink = document.createElement("a");
|
||||
mediaLink.setAttribute("href", attachment.url);
|
||||
mediaLink.setAttribute("rel", relAttributes);
|
||||
mediaLink.appendChild(mediaElement);
|
||||
|
||||
media.appendChild(mediaLink);
|
||||
}
|
||||
});
|
||||
|
||||
comment.appendChild(media);
|
||||
}
|
||||
|
||||
let interactions = document.createElement("footer");
|
||||
|
||||
let boosts = document.createElement("a");
|
||||
boosts.className = "boosts";
|
||||
boosts.setAttribute("href", `${status.url}/reblogs`);
|
||||
|
||||
let boostsIcon = document.createElement("i");
|
||||
boostsIcon.classList.add("ph-bold", "ph-repeat");
|
||||
boosts.appendChild(boostsIcon);
|
||||
boosts.insertAdjacentHTML('beforeend', ` ${status.reblogs_count}`);
|
||||
interactions.appendChild(boosts);
|
||||
|
||||
let faves = document.createElement("a");
|
||||
faves.className = "faves";
|
||||
faves.setAttribute("href", `${status.url}/favourites`);
|
||||
|
||||
let favesIcon = document.createElement("i");
|
||||
favesIcon.classList.add("ph-bold", "ph-star");
|
||||
faves.appendChild(favesIcon);
|
||||
faves.insertAdjacentHTML('beforeend', ` ${status.favourites_count}`);
|
||||
interactions.appendChild(faves);
|
||||
|
||||
if (
|
||||
status.reactions &&
|
||||
Array.isArray(status.reactions) &&
|
||||
status.reactions.length > 0
|
||||
) {
|
||||
let reactions = document.createElement("div");
|
||||
reactions.classList.add("reactions", "overshoot-row");
|
||||
|
||||
status.reactions.forEach(reaction => {
|
||||
let reactionElement = document.createElement("span");
|
||||
reactionElement.className = "reaction";
|
||||
|
||||
if (reaction.url) {
|
||||
// Custom emoji
|
||||
let img = document.createElement("img");
|
||||
img.className = "emoji";
|
||||
img.setAttribute("src", escapeHtml(reaction.url));
|
||||
img.setAttribute("title", `${reaction.name}`);
|
||||
img.setAttribute("width", "24");
|
||||
img.setAttribute("height", "24");
|
||||
reactionElement.appendChild(img);
|
||||
} else {
|
||||
// Unicode emoji
|
||||
let emoji = document.createElement("span");
|
||||
emoji.textContent = reaction.name;
|
||||
reactionElement.appendChild(emoji);
|
||||
}
|
||||
|
||||
// Append the count
|
||||
let count = document.createElement("span");
|
||||
count.textContent = reaction.count;
|
||||
reactionElement.appendChild(count);
|
||||
|
||||
reactions.appendChild(reactionElement);
|
||||
});
|
||||
|
||||
interactions.appendChild(reactions);
|
||||
}
|
||||
|
||||
comment.appendChild(interactions);
|
||||
|
||||
if (status.card != null) {
|
||||
let cardFigure = document.createElement("figure");
|
||||
|
||||
if (status.card.image != null) {
|
||||
let cardImg = document.createElement("img");
|
||||
cardImg.setAttribute("src", status.card.image);
|
||||
cardImg.classList.add("no-hover");
|
||||
cardFigure.appendChild(cardImg);
|
||||
}
|
||||
|
||||
let cardCaption = document.createElement("figcaption");
|
||||
|
||||
let cardTitle = document.createElement("strong");
|
||||
cardTitle.innerHTML = status.card.title;
|
||||
cardCaption.appendChild(cardTitle);
|
||||
|
||||
if (status.card.description != null && status.card.description.length > 0) {
|
||||
let cardDescription = document.createElement("p");
|
||||
cardDescription.innerHTML = status.card.description;
|
||||
cardCaption.appendChild(cardDescription);
|
||||
}
|
||||
|
||||
cardFigure.appendChild(cardCaption);
|
||||
|
||||
let card = document.createElement("a");
|
||||
card.className = "card";
|
||||
card.setAttribute("href", status.card.url);
|
||||
card.setAttribute("rel", relAttributes);
|
||||
card.appendChild(cardFigure);
|
||||
|
||||
comment.appendChild(card);
|
||||
}
|
||||
|
||||
if (op === true) {
|
||||
comment.classList.add("op");
|
||||
instanceBadge.classList.add("op");
|
||||
instanceBadge.setAttribute("title", articleAuthorText);
|
||||
}
|
||||
|
||||
commentsWrapper.appendChild(comment);
|
||||
});
|
||||
}
|
||||
|
||||
else {
|
||||
var statusText = document.createElement("p");
|
||||
statusText.innerHTML = noCommentsText;
|
||||
statusText.setAttribute("id", "comments-status");
|
||||
commentsWrapper.appendChild(statusText);
|
||||
}
|
||||
|
||||
loadCommentsButton.innerHTML = reloadText;
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Error loading comments:', error);
|
||||
})
|
||||
.finally(function () {
|
||||
loadCommentsButton.disabled = false;
|
||||
});
|
||||
}
|
66
static/copy-button.js
Normale Datei
66
static/copy-button.js
Normale Datei
|
@ -0,0 +1,66 @@
|
|||
// Based on https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
let blocks = document.querySelectorAll("pre[class^='language-']");
|
||||
|
||||
blocks.forEach((block) => {
|
||||
if (navigator.clipboard) {
|
||||
// Code block header title
|
||||
let title = document.createElement("span");
|
||||
let lang = block.getAttribute("data-lang");
|
||||
title.innerHTML = lang;
|
||||
|
||||
// Copy button icon
|
||||
let iconCopy = document.createElement("i");
|
||||
iconCopy.classList.add("ph-bold", "ph-copy");
|
||||
|
||||
let iconCheck = document.createElement("i");
|
||||
iconCheck.classList.add("ph-bold", "ph-check-square-offset");
|
||||
|
||||
// Copy button
|
||||
let button = document.createElement("button");
|
||||
let copyCodeText = document.getElementById("copy-code-text").textContent;
|
||||
button.setAttribute("title", copyCodeText);
|
||||
button.appendChild(iconCopy);
|
||||
button.appendChild(iconCheck);
|
||||
|
||||
// Code block header
|
||||
let header = document.createElement("div");
|
||||
header.classList.add("header");
|
||||
|
||||
if (block.classList.contains("z-code")) {
|
||||
header.classList.add("z-code");
|
||||
}
|
||||
|
||||
header.appendChild(title);
|
||||
header.appendChild(button);
|
||||
|
||||
// Container that holds header and the code block itself
|
||||
let container = document.createElement("div");
|
||||
container.classList.add("pre-container");
|
||||
container.appendChild(header);
|
||||
|
||||
// Move code block into the container
|
||||
block.parentNode.insertBefore(container, block);
|
||||
container.appendChild(block);
|
||||
|
||||
button.addEventListener("click", async () => {
|
||||
await copyCode(block, header, button);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function copyCode(block, header, button) {
|
||||
let code = block.querySelector("code");
|
||||
let text = code.innerText;
|
||||
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
header.classList.add("active");
|
||||
button.setAttribute("disabled", true);
|
||||
|
||||
header.addEventListener("animationend", () => {
|
||||
header.classList.remove("active");
|
||||
button.removeAttribute("disabled");
|
||||
}, { once: true });
|
||||
}
|
||||
});
|
BIN
static/favicon.png
Normale Datei
BIN
static/favicon.png
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 817 B |
BIN
static/fonts/geist-mono.woff2
Normale Datei
BIN
static/fonts/geist-mono.woff2
Normale Datei
Binäre Datei nicht angezeigt.
BIN
static/fonts/geist.woff2
Normale Datei
BIN
static/fonts/geist.woff2
Normale Datei
Binäre Datei nicht angezeigt.
BIN
static/fonts/phosphor-bold.woff2
Normale Datei
BIN
static/fonts/phosphor-bold.woff2
Normale Datei
Binäre Datei nicht angezeigt.
4623
static/phosphor-bold.css
Normale Datei
4623
static/phosphor-bold.css
Normale Datei
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
236
static/search.js
Normale Datei
236
static/search.js
Normale Datei
|
@ -0,0 +1,236 @@
|
|||
// Based on https://github.com/cydave/zola-theme-papermod/blob/fab7cd04833f0c78264b433a4fb1f4b999ef0399/static/js/search.js
|
||||
|
||||
// Debounce function definition
|
||||
function debounce(func, wait, immediate) {
|
||||
var timeout;
|
||||
return function () {
|
||||
var context = this, args = arguments;
|
||||
var later = function () {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
}
|
||||
|
||||
// Taken from mdbook
|
||||
// The strategy is as follows:
|
||||
// First, assign a value to each word in the document:
|
||||
// Words that correspond to search terms (stemmer aware): 40
|
||||
// Normal words: 2
|
||||
// First word in a sentence: 8
|
||||
// Then use a sliding window with a constant number of words and count the
|
||||
// sum of the values of the words within the window. Then use the window that got the
|
||||
// maximum sum. If there are multiple maximas, then get the last one.
|
||||
// Enclose the terms in <b>.
|
||||
function makeTeaser(body, terms) {
|
||||
var TERM_WEIGHT = 40;
|
||||
var NORMAL_WORD_WEIGHT = 2;
|
||||
var FIRST_WORD_WEIGHT = 8;
|
||||
var TEASER_MAX_WORDS = 30;
|
||||
|
||||
var stemmedTerms = terms.map(function (w) {
|
||||
return elasticlunr.stemmer(w.toLowerCase());
|
||||
});
|
||||
var termFound = false;
|
||||
var index = 0;
|
||||
var weighted = []; // contains elements of ["word", weight, index_in_document]
|
||||
|
||||
// split in sentences, then words
|
||||
var sentences = body.toLowerCase().split(". ");
|
||||
|
||||
for (var i in sentences) {
|
||||
var words = sentences[i].split(" ");
|
||||
var value = FIRST_WORD_WEIGHT;
|
||||
|
||||
for (var j in words) {
|
||||
var word = words[j];
|
||||
|
||||
if (word.length > 0) {
|
||||
for (var k in stemmedTerms) {
|
||||
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
|
||||
value = TERM_WEIGHT;
|
||||
termFound = true;
|
||||
}
|
||||
}
|
||||
weighted.push([word, value, index]);
|
||||
value = NORMAL_WORD_WEIGHT;
|
||||
}
|
||||
|
||||
index += word.length;
|
||||
index += 1; // ' ' or '.' if last word in sentence
|
||||
}
|
||||
|
||||
index += 1; // because we split at a two-char boundary '. '
|
||||
}
|
||||
|
||||
if (weighted.length === 0) {
|
||||
return body;
|
||||
}
|
||||
|
||||
var windowWeights = [];
|
||||
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
|
||||
// We add a window with all the weights first
|
||||
var curSum = 0;
|
||||
for (var i = 0; i < windowSize; i++) {
|
||||
curSum += weighted[i][1];
|
||||
}
|
||||
windowWeights.push(curSum);
|
||||
|
||||
for (var i = 0; i < weighted.length - windowSize; i++) {
|
||||
curSum -= weighted[i][1];
|
||||
curSum += weighted[i + windowSize][1];
|
||||
windowWeights.push(curSum);
|
||||
}
|
||||
|
||||
// If we didn't find the term, just pick the first window
|
||||
var maxSumIndex = 0;
|
||||
if (termFound) {
|
||||
var maxFound = 0;
|
||||
// backwards
|
||||
for (var i = windowWeights.length - 1; i >= 0; i--) {
|
||||
if (windowWeights[i] > maxFound) {
|
||||
maxFound = windowWeights[i];
|
||||
maxSumIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var teaser = [];
|
||||
var startIndex = weighted[maxSumIndex][2];
|
||||
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
|
||||
var word = weighted[i];
|
||||
if (startIndex < word[2]) {
|
||||
// missing text from index to start of `word`
|
||||
teaser.push(body.substring(startIndex, word[2]));
|
||||
startIndex = word[2];
|
||||
}
|
||||
|
||||
// add <strong> around search terms
|
||||
if (word[1] === TERM_WEIGHT) {
|
||||
teaser.push("<strong>");
|
||||
}
|
||||
startIndex = word[2] + word[0].length;
|
||||
teaser.push(body.substring(word[2], startIndex));
|
||||
|
||||
if (word[1] === TERM_WEIGHT) {
|
||||
teaser.push("</strong>");
|
||||
}
|
||||
}
|
||||
teaser.push("…");
|
||||
return teaser.join("");
|
||||
}
|
||||
|
||||
function formatSearchResultItem(item, terms) {
|
||||
// Adjust this to match your desired result item structure
|
||||
return '<div class="item">'
|
||||
+ `<a href="${item.ref}">${item.doc.title}</a>`
|
||||
+ `<span>${makeTeaser(item.doc.body, terms)}</span>`
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
function initSearch() {
|
||||
var searchModal = document.getElementById("search-modal"); // Full-screen modal
|
||||
var searchModalContent = document.getElementById("search-modal-content"); // Actual modal box
|
||||
var searchInput = document.getElementById("search-input"); // Search input
|
||||
var searchResults = document.getElementById("search-results"); // Search results
|
||||
var searchButton = document.getElementById("search"); // Search button
|
||||
var MAX_ITEMS = 10;
|
||||
|
||||
var options = {
|
||||
bool: "AND",
|
||||
fields: {
|
||||
title: { boost: 2 },
|
||||
body: { boost: 1 },
|
||||
}
|
||||
};
|
||||
var currentTerm = "";
|
||||
var index;
|
||||
|
||||
var initIndex = async function () {
|
||||
if (index === undefined) {
|
||||
if (typeof window.searchIndex !== "undefined") {
|
||||
index = elasticlunr.Index.load(window.searchIndex);
|
||||
} else {
|
||||
let response = await fetch(`/search_index.${document.documentElement.lang}.json`);
|
||||
index = elasticlunr.Index.load(await response.json());
|
||||
}
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
// Open search modal when clicking the search button
|
||||
if (searchButton) {
|
||||
searchButton.addEventListener("click", function () {
|
||||
searchModal.classList.add("active");
|
||||
searchModal.addEventListener("transitionend", function handler() {
|
||||
searchInput.focus();
|
||||
searchModal.removeEventListener("transitionend", handler);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
// Open search modal on "/" key press
|
||||
window.addEventListener("keydown", (event) => {
|
||||
if (event.key === "/" && document.activeElement.tagName !== "INPUT" && document.activeElement.tagName !== "TEXTAREA") {
|
||||
event.preventDefault();
|
||||
searchModal.classList.add("active");
|
||||
searchModal.addEventListener("transitionend", function handler() {
|
||||
searchInput.focus();
|
||||
searchModal.removeEventListener("transitionend", handler);
|
||||
}, { once: true });
|
||||
}
|
||||
});
|
||||
|
||||
// Close search modal on Escape key
|
||||
window.addEventListener("keydown", (event) => {
|
||||
if (event.key === "Escape") {
|
||||
searchModal.classList.remove("active");
|
||||
}
|
||||
});
|
||||
|
||||
// Close search modal when clicking outside search-modal-content
|
||||
searchModal.addEventListener("click", function (e) {
|
||||
if (!searchModalContent.contains(e.target)) {
|
||||
searchModal.classList.remove("active");
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent clicks inside modal content from closing it
|
||||
searchModalContent.addEventListener("click", function (e) {
|
||||
e.stopPropagation(); // Stops event from reaching searchModal click handler
|
||||
});
|
||||
|
||||
// Search input event
|
||||
searchInput.addEventListener("keyup", debounce(async function () {
|
||||
var term = searchInput.value.trim();
|
||||
if (term === currentTerm) return;
|
||||
|
||||
searchResults.style.display = term === "" ? "none" : "flex";
|
||||
searchResults.innerHTML = ""; // Clear previous results
|
||||
currentTerm = term;
|
||||
if (term === "") return;
|
||||
|
||||
var results = (await initIndex()).search(term, options);
|
||||
if (results.length === 0) {
|
||||
searchResults.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert formatted search result items
|
||||
for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) {
|
||||
searchResults.innerHTML += formatSearchResultItem(results[i], term.split(" "));
|
||||
}
|
||||
}, 150));
|
||||
}
|
||||
|
||||
if (document.readyState === "complete" ||
|
||||
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
||||
) {
|
||||
initSearch();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", initSearch);
|
||||
}
|
78
static/syntax-theme-dark.css
Normale Datei
78
static/syntax-theme-dark.css
Normale Datei
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* theme "Monokai Pro" generated by syntect
|
||||
*/
|
||||
|
||||
.z-code {
|
||||
color: #fcfcfa;
|
||||
background-color: #2d2a2e;
|
||||
}
|
||||
|
||||
.z-comment {
|
||||
color: #727072;
|
||||
}
|
||||
.z-string {
|
||||
color: #ffd866;
|
||||
}
|
||||
.z-constant.z-numeric {
|
||||
color: #ab9df2;
|
||||
}
|
||||
.z-constant.z-language {
|
||||
color: #ab9df2;
|
||||
}
|
||||
.z-constant.z-character, .z-constant.z-other {
|
||||
color: #ab9df2;
|
||||
}
|
||||
.z-variable {
|
||||
}
|
||||
.z-keyword {
|
||||
color: #ff6188;
|
||||
}
|
||||
.z-storage {
|
||||
color: #ff6188;
|
||||
}
|
||||
.z-storage.z-type {
|
||||
color: #78dce8;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-class {
|
||||
color: #a9dc76;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.z-entity.z-other.z-inherited-class {
|
||||
color: #a9dc76;
|
||||
text-decoration: underline;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-function {
|
||||
color: #a9dc76;
|
||||
}
|
||||
.z-variable.z-parameter {
|
||||
color: #fc9867;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-tag {
|
||||
color: #ff6188;
|
||||
}
|
||||
.z-entity.z-other.z-attribute-name {
|
||||
color: #a9dc76;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-support.z-function {
|
||||
color: #78dce8;
|
||||
}
|
||||
.z-support.z-constant {
|
||||
color: #78dce8;
|
||||
}
|
||||
.z-support.z-type, .z-support.z-class {
|
||||
color: #fcfcfa;
|
||||
}
|
||||
.z-support.z-other.z-variable {
|
||||
}
|
||||
.z-invalid {
|
||||
color: #fcfcfa;
|
||||
background-color: #ff6188;
|
||||
}
|
||||
.z-invalid.z-deprecated {
|
||||
color: #fcfcfa;
|
||||
background-color: #ae81ff;
|
||||
}
|
78
static/syntax-theme-light.css
Normale Datei
78
static/syntax-theme-light.css
Normale Datei
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* theme "Monokai Pro Light" generated by syntect
|
||||
*/
|
||||
|
||||
.z-code {
|
||||
color: #29242a;
|
||||
background-color: #faf4f2;
|
||||
}
|
||||
|
||||
.z-comment {
|
||||
color: #918c8e;
|
||||
}
|
||||
.z-string {
|
||||
color: #cc7a0a;
|
||||
}
|
||||
.z-constant.z-numeric {
|
||||
color: #7058be;
|
||||
}
|
||||
.z-constant.z-language {
|
||||
color: #7058be;
|
||||
}
|
||||
.z-constant.z-character, .z-constant.z-other {
|
||||
color: #7058be;
|
||||
}
|
||||
.z-variable {
|
||||
}
|
||||
.z-keyword {
|
||||
color: #e14775;
|
||||
}
|
||||
.z-storage {
|
||||
color: #e14775;
|
||||
}
|
||||
.z-storage.z-type {
|
||||
color: #1c8ca8;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-class {
|
||||
color: #269d69;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.z-entity.z-other.z-inherited-class {
|
||||
color: #269d69;
|
||||
text-decoration: underline;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-function {
|
||||
color: #269d69;
|
||||
}
|
||||
.z-variable.z-parameter {
|
||||
color: #e16032;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-entity.z-name.z-tag {
|
||||
color: #e14775;
|
||||
}
|
||||
.z-entity.z-other.z-attribute-name {
|
||||
color: #269d69;
|
||||
font-style: italic;
|
||||
}
|
||||
.z-support.z-function {
|
||||
color: #1c8ca8;
|
||||
}
|
||||
.z-support.z-constant {
|
||||
color: #1c8ca8;
|
||||
}
|
||||
.z-support.z-type, .z-support.z-class {
|
||||
color: #29242a;
|
||||
}
|
||||
.z-support.z-other.z-variable {
|
||||
}
|
||||
.z-invalid {
|
||||
color: #fcfcfa;
|
||||
background-color: #ff6188;
|
||||
}
|
||||
.z-invalid.z-deprecated {
|
||||
color: #fcfcfa;
|
||||
background-color: #7058be;
|
||||
}
|
295
sublime/themes/monokai-pro-dark.tmTheme
Normale Datei
295
sublime/themes/monokai-pro-dark.tmTheme
Normale Datei
|
@ -0,0 +1,295 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!-- Generated by: TmTheme-Editor -->
|
||||
<!-- ============================================ -->
|
||||
<!-- app: http://tmtheme-editor.herokuapp.com -->
|
||||
<!-- code: https://github.com/aziz/tmTheme-Editor -->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Monokai Pro</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#2D2A2E</string>
|
||||
<key>caret</key>
|
||||
<string>#FCFCFA</string>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
<key>invisibles</key>
|
||||
<string>#5B595C</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#403E41</string>
|
||||
<key>selection</key>
|
||||
<string>#403E41</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#727072</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FFD866</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AB9DF2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Built-in constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AB9DF2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>User-defined constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AB9DF2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FF6188</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#FF6188</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#78DCE8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#A9DC76</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Inherited class</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.inherited-class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#A9DC76</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#A9DC76</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function argument</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#FC9867</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#FF6188</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string> italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#A9DC76</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#78DCE8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library constant</string>
|
||||
<key>scope</key>
|
||||
<string>support.constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#78DCE8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library class/type</string>
|
||||
<key>scope</key>
|
||||
<string>support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library variable</string>
|
||||
<key>scope</key>
|
||||
<string>support.other.variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#FF6188</string>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid deprecated</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.deprecated</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#AE81FF</string>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string>
|
||||
<key>colorSpaceName</key>
|
||||
<string>sRGB</string>
|
||||
<key>semanticClass</key>
|
||||
<string>theme.dark.monokai</string>
|
||||
</dict>
|
||||
</plist>
|
295
sublime/themes/monokai-pro-light.tmTheme
Normale Datei
295
sublime/themes/monokai-pro-light.tmTheme
Normale Datei
|
@ -0,0 +1,295 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!-- Generated by: TmTheme-Editor -->
|
||||
<!-- ============================================ -->
|
||||
<!-- app: http://tmtheme-editor.herokuapp.com -->
|
||||
<!-- code: https://github.com/aziz/tmTheme-Editor -->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Monokai Pro Light</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#FAF4F2</string>
|
||||
<key>caret</key>
|
||||
<string>#29242A</string>
|
||||
<key>foreground</key>
|
||||
<string>#29242A</string>
|
||||
<key>invisibles</key>
|
||||
<string>#918C8E</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#29242A0D</string>
|
||||
<key>selection</key>
|
||||
<string>#29242A0D</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#918C8E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#CC7A0A</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#7058BE</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Built-in constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#7058BE</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>User-defined constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#7058BE</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E14775</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#E14775</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#1C8CA8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#269D69</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Inherited class</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.inherited-class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#269D69</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#269D69</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function argument</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#E16032</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#E14775</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string> italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#269D69</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#1C8CA8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library constant</string>
|
||||
<key>scope</key>
|
||||
<string>support.constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#1C8CA8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library class/type</string>
|
||||
<key>scope</key>
|
||||
<string>support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#29242A</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library variable</string>
|
||||
<key>scope</key>
|
||||
<string>support.other.variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#FF6188</string>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid deprecated</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.deprecated</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#7058BE</string>
|
||||
<key>foreground</key>
|
||||
<string>#FCFCFA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string>
|
||||
<key>colorSpaceName</key>
|
||||
<string>sRGB</string>
|
||||
<key>semanticClass</key>
|
||||
<string>theme.dark.monokai_pro</string>
|
||||
</dict>
|
||||
</plist>
|
1
themes/ametrine
Submodul
1
themes/ametrine
Submodul
|
@ -0,0 +1 @@
|
|||
Subproject commit ea8c9710c4596b39de8e01ee1697cd042c009bdf
|
Laden …
Tabelle hinzufügen
In neuem Issue referenzieren