added theme directory
112
novemila/themes/typo/.gitignore
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
### Hugo ###
|
||||||
|
# Generated files by hugo
|
||||||
|
/public/
|
||||||
|
/resources/_gen/
|
||||||
|
/assets/jsconfig.json
|
||||||
|
hugo_stats.json
|
||||||
|
|
||||||
|
# Executable may be added to repository
|
||||||
|
hugo.exe
|
||||||
|
hugo.darwin
|
||||||
|
hugo.linux
|
||||||
|
|
||||||
|
# Temporary lock file while building
|
||||||
|
/.hugo_build.lock
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
128
novemila/themes/typo/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
19
novemila/themes/typo/CONTRIBUTING.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# How to contribute to Typo
|
||||||
|
|
||||||
|
The goal of this theme is to be as simple as possible, hence adding or changing existing
|
||||||
|
features need some thought.
|
||||||
|
|
||||||
|
Any change that is too niche or heavily tailored to a specific developer's need will be rejected, as
|
||||||
|
that would make some features cumbersome to set up.
|
||||||
|
To avoid unnecessary work, please start a discussion or open an issue with a proposal.
|
||||||
|
|
||||||
|
Any other reasonable changes are more than welcome, keep in mind the guidelines:
|
||||||
|
- keep the code as minimal as possible, and avoid comments in the code unless needed;
|
||||||
|
- keep the parameters (e.g. in hugo.toml) as concise and clear as possible;
|
||||||
|
- update the [wiki](https://github.com/tomfran/typo/tree/main/wiki) if needed, trying to maintain the current style of writing;
|
||||||
|
- refrain from breaking existing behavior, for example, make a new feature disabled by default;
|
||||||
|
- squash your change in a single commit.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
Thank you, <br>
|
||||||
|
Francesco
|
21
novemila/themes/typo/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Francesco Tomaselli
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
45
novemila/themes/typo/README.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|

|
||||||
|
|
||||||
|
# Typo, a Hugo theme.
|
||||||
|
|
||||||
|
Typo is a theme backed by simplicity, as you can see in the screenshots below. The goal was to have a website centered around content and nothing more.
|
||||||
|
|
||||||
|
[](https://tomfran.github.io/typo-wiki/)
|
||||||
|
[](https://themes.gohugo.io/themes/typo/)
|
||||||
|
[](https://github.com/tomfran/typo/releases/latest)
|
||||||
|
[](https://github.com/tomfran/typo/commits/)
|
||||||
|
|
||||||
|
**Homepage**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Article**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 1 Wiki
|
||||||
|
|
||||||
|
Typo's [Wiki](https://tomfran.github.io/typo-wiki/) is the place to find instructions on how to [setup](https://tomfran.github.io/typo-wiki/setup) the theme and an overview of the available [features](https://tomfran.github.io/typo-wiki/features).
|
||||||
|
|
||||||
|
Some of the most relevant are: heading auto-numbering, dark mode, color palettes, dark and light images, comments, etc.
|
||||||
|
|
||||||
|
## 2 Support
|
||||||
|
|
||||||
|
If you use the theme or found it useful you can support me by leaving a star ⭐ to Typo's Github repository.
|
||||||
|
|
||||||
|
[Contributions](https://github.com/tomfran/typo/blob/main/CONTRIBUTING.md) are always welcome, feel free to open issues and PRs with fixes or new features.
|
||||||
|
|
||||||
|
## 3 Typo Users
|
||||||
|
|
||||||
|
If you're using Typo for your website, feel free to add your website to [the list](https://github.com/tomfran/typo/blob/main/USERS.md) alongside what you do! 😊
|
||||||
|
|
||||||
|
## 4 Questions or ideas?
|
||||||
|
|
||||||
|
Use the [discussion tab](https://github.com/tomfran/typo/discussions) to share ideas/tips/questions about Typo or Hugo in general!
|
||||||
|
|
||||||
|
## 5 References
|
||||||
|
|
||||||
|
The SVGs for social icons are taken from [Simple Icons](https://github.com/simple-icons/simple-icons).
|
||||||
|
Every SVG present on the website is usable on the theme.
|
10
novemila/themes/typo/USERS.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Typo Users
|
||||||
|
|
||||||
|
- https://tomfran.github.io, **tomfran**, Software Engineer
|
||||||
|
- https://arunmathaisk.in/, **Arun Mathai S K**, Software Engineer
|
||||||
|
- https://zohaibkhalid.com, **Muhammad Zohaib Khalid**, Data Engineer
|
||||||
|
- https://as215887.net, **Serhiy Bobrov**, Personal Autonomous System
|
||||||
|
- https://smdp26.github.io/, **Soumyadeep Paul**, PhD
|
||||||
|
- https://aadityathapa.github.io/, **Aaditya Thapa**, Data Analyst
|
||||||
|
- https://automagic.blog, **Sangeeth Sudheer**, UX Engineer
|
||||||
|
- https://kmiziz.xyz, **Vasily Negrebetskiy**, Software Engineer
|
5
novemila/themes/typo/archetypes/default.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
+++
|
||||||
|
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||||
|
date = {{ .Date }}
|
||||||
|
draft = true
|
||||||
|
+++
|
15
novemila/themes/typo/assets/css/colors/base16-cupcake.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(88, 80, 98); /*base07*/
|
||||||
|
--content-secondary: rgb(165, 157, 175); /*base04*/
|
||||||
|
--background: rgb(251, 241, 242); /*base00*/
|
||||||
|
--code-background: rgb(242, 241, 244); /*base01*/
|
||||||
|
--code-border: rgb(216, 213, 221); /*base02*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(251, 241, 242); /*base00*/
|
||||||
|
--content-secondary: rgb(191, 185, 198); /*base03*/
|
||||||
|
--background: rgb(88, 80, 98); /*base07*/
|
||||||
|
--code-background: rgb(114, 103, 126); /*base06*/
|
||||||
|
--code-border: rgb(139, 129, 152); /*base05*/
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/base16-default.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(24, 24, 24); /*base07*/
|
||||||
|
--content-secondary: rgb(88, 88, 88); /*base04*/
|
||||||
|
--background: rgb(248, 248, 248); /*base00*/
|
||||||
|
--code-background: rgb(232, 232, 232); /*base01*/
|
||||||
|
--code-border: rgb(216, 216, 216); /*base02*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(248, 248, 248); /*base00*/
|
||||||
|
--content-secondary: rgb(184, 184, 184); /*base03*/
|
||||||
|
--background: rgb(24, 24, 24); /*base07*/
|
||||||
|
--code-background: rgb(40, 40, 40); /*base06*/
|
||||||
|
--code-border: rgb(56, 56, 56); /*base05*/
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/base16-eighties.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(45, 45, 45); /*base00*/
|
||||||
|
--content-secondary: rgb(116, 115, 105); /*base03*/
|
||||||
|
--background: rgb(242, 240, 236); /*base07*/
|
||||||
|
--code-background: rgb(232, 230, 223); /*base06*/
|
||||||
|
--code-border: rgb(211, 208, 200); /*base05*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(242, 240, 236); /*base07*/
|
||||||
|
--content-secondary: rgb(160, 159, 147); /*base04*/
|
||||||
|
--background: rgb(45, 45, 45); /*base00*/
|
||||||
|
--code-background: rgb(57, 57, 57); /*base01*/
|
||||||
|
--code-border: rgb(81, 81, 81); /*base02*/
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/base16-mocha.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(59, 50, 40); /*base00*/
|
||||||
|
--content-secondary: rgb(126, 112, 90); /*base03*/
|
||||||
|
--background: rgb(245, 238, 235); /*base07*/
|
||||||
|
--code-background: rgb(233, 225, 221); /*base06*/
|
||||||
|
--code-border: rgb(208, 200, 198); /*base05*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(245, 238, 235); /*base07*/
|
||||||
|
--content-secondary: rgb(184, 175, 173); /*base04*/
|
||||||
|
--background: rgb(59, 50, 40); /*base00*/
|
||||||
|
--code-background: rgb(83, 70, 54); /*base01*/
|
||||||
|
--code-border: rgb(100, 82, 64); /*base02*/
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/base16-ocean.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(43, 48, 59); /*base00*/
|
||||||
|
--content-secondary: rgb(101, 115, 126); /*base03*/
|
||||||
|
--background: rgb(239, 241, 245); /*base07*/
|
||||||
|
--code-background: rgb(223, 225, 232); /*base06*/
|
||||||
|
--code-border: rgb(192, 197, 206); /*base05*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(239, 241, 245); /*base07*/
|
||||||
|
--content-secondary: rgb(167, 173, 186); /*base04*/
|
||||||
|
--background: rgb(43, 48, 59); /*base00*/
|
||||||
|
--code-background: rgb(52, 61, 70); /*base01*/
|
||||||
|
--code-border: rgb(79, 91, 102); /*base02*/
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/catpuccin.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(76, 79, 105);
|
||||||
|
--content-secondary: rgb(108, 111, 133);
|
||||||
|
--background: rgb(239, 241, 245);
|
||||||
|
--code-background: rgb(230, 233, 239);
|
||||||
|
--code-border: rgb(188, 192, 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(198, 208, 245);
|
||||||
|
--content-secondary: rgb(165, 173, 206);
|
||||||
|
--background: rgb(48, 52, 70);
|
||||||
|
--code-background: rgb(41, 44, 60);
|
||||||
|
--code-border: rgb(81, 87, 109);
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/default.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(36, 36, 36);
|
||||||
|
--content-secondary: rgb(117, 117, 117);
|
||||||
|
--background: rgb(255, 255, 255);
|
||||||
|
--code-background: rgb(249, 249, 249);
|
||||||
|
--code-border: rgb(229, 229, 229);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(218, 218, 218);
|
||||||
|
--content-secondary: rgb(140, 140, 140);
|
||||||
|
--background: rgb(20, 20, 20);
|
||||||
|
--code-background: rgb(30, 30, 30);
|
||||||
|
--code-border: rgb(50, 50, 50);
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/eink.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(0, 0, 0);
|
||||||
|
--content-secondary: rgb(0, 0, 0);
|
||||||
|
--background: rgb(255, 255, 255);
|
||||||
|
--code-background: rgb(255, 255, 255);
|
||||||
|
--code-border: rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(255, 255, 255);
|
||||||
|
--content-secondary: rgb(255, 255, 255);
|
||||||
|
--background: rgb(0, 0, 0);
|
||||||
|
--code-background: rgb(0, 0, 0);
|
||||||
|
--code-border: rgb(255, 255, 255);
|
||||||
|
}
|
15
novemila/themes/typo/assets/css/colors/gruvebox.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:root {
|
||||||
|
--content-primary: rgb(60, 56, 54);
|
||||||
|
--content-secondary: rgb(148, 133, 112);
|
||||||
|
--background: rgb(251, 241, 199);
|
||||||
|
--code-background: rgb(241, 231, 189);
|
||||||
|
--code-border: rgb(178, 163, 142);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--content-primary: rgb(235, 219, 178);
|
||||||
|
--content-secondary: rgb(132, 122, 114);
|
||||||
|
--background: rgb(40, 40, 40);
|
||||||
|
--code-background: rgb(50, 50, 50);
|
||||||
|
--code-border: rgb(112, 102, 94);
|
||||||
|
}
|
1
novemila/themes/typo/assets/css/custom.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* Place custom css here */
|
47
novemila/themes/typo/assets/css/fonts.css
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Literata';
|
||||||
|
src: url('/fonts/Literata/Literata-Light.woff2') format('woff2');
|
||||||
|
font-weight: light;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Literata';
|
||||||
|
src: url('/fonts/Literata/Literata-LightItalic.woff2') format('woff2');
|
||||||
|
font-weight: light;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Literata';
|
||||||
|
src: url('/fonts/Literata/Literata-SemiBold.woff2') format('woff2');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Literata';
|
||||||
|
src: url('/fonts/Literata/Literata-SemiBoldItalic.woff2') format('woff2');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monaspace';
|
||||||
|
src: url('/fonts/Monaspace/MonaspaceArgon-Regular.woff') format('woff');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monaspace';
|
||||||
|
src: url('/fonts/Monaspace/MonaspaceArgon-SemiBold.woff') format('woff');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
601
novemila/themes/typo/assets/css/main.css
Normal file
@@ -0,0 +1,601 @@
|
|||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--font-body);
|
||||||
|
margin: auto;
|
||||||
|
max-width: var(--main-width);
|
||||||
|
padding-left: var(--main-padding);
|
||||||
|
padding-right: var(--main-padding);
|
||||||
|
color: var(--content-primary);
|
||||||
|
background: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
min-height: var(--content-height) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-top: var(--h1-margin-top);
|
||||||
|
margin-bottom: var(--h1-margin-bottom);
|
||||||
|
font-size: var(--h1-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: var(--h2-margin-top);
|
||||||
|
margin-bottom: var(--h2-margin-bottom);
|
||||||
|
font-size: var(--h2-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-size: var(--hx-font-size);
|
||||||
|
margin-top: var(--hx-margin-top);
|
||||||
|
margin-bottom: var(--hx-margin-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
.anchor {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--content-secondary);
|
||||||
|
visibility: hidden;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .anchor {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: var(--p-margin-top);
|
||||||
|
margin-bottom: var(--p-margin-bottom);
|
||||||
|
font-size: var(--p-font-size);
|
||||||
|
line-height: var(--p-line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-left: var(--li-indent);
|
||||||
|
|
||||||
|
&:has(> input[type="checkbox"]) {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > input[type="checkbox"] {
|
||||||
|
width: var(--li-checkbox-size);
|
||||||
|
height: var(--li-checkbox-size);
|
||||||
|
margin: 0 0.2em 0.15em -1.25em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
.dark & {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
|
||||||
|
.copy-code-button {
|
||||||
|
background-color: var(--background);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
padding: 3px 6px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
border-radius: var(--copy-code-button-border-radius);
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
display: none;
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre:hover .copy-code-button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
position: relative;
|
||||||
|
padding: var(--code-padding);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
overflow: scroll;
|
||||||
|
border-radius: var(--code-border-radius);
|
||||||
|
margin-top: var(--code-margin-top);
|
||||||
|
margin-bottom: var(--code-margin-bottom);
|
||||||
|
background-color: var(--code-background) !important;
|
||||||
|
overflow-x: auto;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
code span {
|
||||||
|
display: inline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-font-feature-settings: "liga=1, dlig=1";
|
||||||
|
-ms-font-feature-settings: "liga", "dlig";
|
||||||
|
-webkit-font-feature-settings: "liga", "dlig";
|
||||||
|
-o-font-feature-settings: "liga", "dlig";
|
||||||
|
font-feature-settings: "liga", "dlig";
|
||||||
|
font-variant-ligatures: contextual;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: .9em;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.katex-display {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.katex-display::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footnotes */
|
||||||
|
|
||||||
|
.footnotes {
|
||||||
|
margin-top: 3rem;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--content-secondary);
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding-top: var(--header-top-gap);
|
||||||
|
margin-bottom: var(--header-bottom-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header p {
|
||||||
|
font-size: small;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
margin-top: var(--header-menu-top-gap);
|
||||||
|
margin-right: var(--header-menu-side-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 2.6em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
|
||||||
|
footer {
|
||||||
|
font-size: small;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
max-height: var(--footer-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
margin-left: .2rem;
|
||||||
|
margin-right: .2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Posts list */
|
||||||
|
|
||||||
|
.post-line {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-line {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-line p {
|
||||||
|
margin-top: 0rem;
|
||||||
|
margin-bottom: 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-date {
|
||||||
|
font-size: small;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: 120px;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 1rem;
|
||||||
|
margin-top: 0rem;
|
||||||
|
margin-bottom: 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-summary {
|
||||||
|
font-size: small;
|
||||||
|
margin-top: .2rem !important;
|
||||||
|
/* font-style: italic; */
|
||||||
|
color: var(--content-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-container {
|
||||||
|
padding-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 0rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-control {
|
||||||
|
min-width: 3rem;
|
||||||
|
margin-left: .5rem;
|
||||||
|
margin-right: .5rem;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-number {
|
||||||
|
min-width: 3rem;
|
||||||
|
margin-left: .5rem;
|
||||||
|
margin-right: .5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Social Icons */
|
||||||
|
|
||||||
|
.social-icons {
|
||||||
|
padding: 12px 0;
|
||||||
|
margin-bottom: var(--social-icons-bottom-margin)
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons a:not(:last-of-type) {
|
||||||
|
margin-inline-end: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icons a svg {
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Single post page */
|
||||||
|
|
||||||
|
.single-intro-container {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-title {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-readtime {
|
||||||
|
margin-top: .5rem;
|
||||||
|
color: var(--content-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-summary {
|
||||||
|
margin-bottom: 0;
|
||||||
|
color: var(--content-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-content {
|
||||||
|
margin-bottom: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-tags {
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-tags span {
|
||||||
|
margin-right: .3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Single pagination */
|
||||||
|
|
||||||
|
.single-pagination {
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination a {
|
||||||
|
margin-left: .4rem;
|
||||||
|
margin-right: .4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination hr {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination-text {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination-prev {
|
||||||
|
min-width: 50%;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination-next {
|
||||||
|
min-width: 50%;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination-container-next {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100%;
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-pagination-container-prev {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100%;
|
||||||
|
padding: .5rem;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table of contents */
|
||||||
|
|
||||||
|
.toc {
|
||||||
|
font-size: var(--p-font-size);
|
||||||
|
line-height: calc(.9 * var(--p-line-height));
|
||||||
|
margin-top: var(--toc-margin-top);
|
||||||
|
margin-bottom: var(--toc-margin-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc ul {
|
||||||
|
margin-top: .1rem;
|
||||||
|
margin-bottom: .1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc li {
|
||||||
|
margin-top: .1rem;
|
||||||
|
margin-bottom: .1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Autonumbering */
|
||||||
|
|
||||||
|
.autonumber {
|
||||||
|
counter-reset: h2-counter 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h2 {
|
||||||
|
counter-increment: h2-counter 1;
|
||||||
|
counter-reset: h3-counter 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h3 {
|
||||||
|
counter-increment: h3-counter 1;
|
||||||
|
counter-reset: h4-counter 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h4 {
|
||||||
|
counter-increment: h4-counter 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h2:before {
|
||||||
|
content: counter(h2-counter) "\00a0\00a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h3:before {
|
||||||
|
content: counter(h2-counter) "." counter(h3-counter) "\00a0\00a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.autonumber h4:before {
|
||||||
|
content: counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) "\00a0\00a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* images */
|
||||||
|
|
||||||
|
figure>div {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: var(--figure-img-max-height);
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .img-light {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light .img-dark {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-small div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-small img {
|
||||||
|
max-height: calc(var(--figure-img-max-height) * 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-small div:first-child {
|
||||||
|
height: 80%;
|
||||||
|
width: 80%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-full div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-full img {
|
||||||
|
height: auto;
|
||||||
|
width: 100vw !important;
|
||||||
|
max-width: 100vw !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
color: var(--content-secondary);
|
||||||
|
padding-left: var(--caption-padding);
|
||||||
|
padding-right: var(--caption-padding);
|
||||||
|
font-size: var(--caption-font-size);
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 404 */
|
||||||
|
|
||||||
|
.not-found {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-found div {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-found div h1 {
|
||||||
|
font-size: 6rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* breadcrumbs */
|
||||||
|
|
||||||
|
.breadcrumbs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 2px;
|
||||||
|
font-size: small;
|
||||||
|
margin-bottom: calc(-0.5 * var(--h1-margin-top));
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comments */
|
||||||
|
|
||||||
|
.giscus {
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Back to top */
|
||||||
|
|
||||||
|
.back-to-top {
|
||||||
|
text-align: center;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: small;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
/* margin-top: -3rem; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code in paragraphs */
|
||||||
|
|
||||||
|
p code {
|
||||||
|
background-color: var(--code-background);
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: var(--table-margin-top);
|
||||||
|
margin-bottom: var(--table-margin-bottom);
|
||||||
|
font-size: var(--p-font-size);
|
||||||
|
line-height: var(--p-line-height);
|
||||||
|
color: var(--content-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: var(--table-cell-padding);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: var(--code-background);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
table code {
|
||||||
|
background-color: var(--code-background);
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quotes */
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 1.5rem;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
border-left: solid 2px;
|
||||||
|
color: var(--content-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote p {
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
117
novemila/themes/typo/assets/css/reset.css
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
*,
|
||||||
|
::after,
|
||||||
|
::before {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
overflow-y: scroll;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
button,
|
||||||
|
body,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-word;
|
||||||
|
background: var(--theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
main,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
table {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
figure,
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
padding: 0;
|
||||||
|
font: inherit;
|
||||||
|
background: 0 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input[type=button],
|
||||||
|
input[type=submit] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill,
|
||||||
|
textarea:-webkit-autofill {
|
||||||
|
box-shadow: 0 0 0 50px var(--theme) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
20
novemila/themes/typo/assets/css/utils.css
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monospace {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
}
|
82
novemila/themes/typo/assets/css/vars.css
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
:root {
|
||||||
|
--main-width: 780px;
|
||||||
|
--main-padding: 1.4em;
|
||||||
|
--main-padding-bottom: 3rem;
|
||||||
|
|
||||||
|
--caption-padding: calc(.25 * var(--main-padding));
|
||||||
|
|
||||||
|
/* header settings */
|
||||||
|
--header-top-gap: 2rem;
|
||||||
|
--header-bottom-gap: 2rem;
|
||||||
|
--header-menu-side-gap: .5rem;
|
||||||
|
--header-menu-top-gap: 1rem;
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-body: 'Literata', Georgia, Cambria, 'Noto Serif', 'Droif Serif', ui-serif, serif;
|
||||||
|
--font-mono: "Monaspace", ui-monospace, monospace;
|
||||||
|
|
||||||
|
--h1-margin-top: 2rem;
|
||||||
|
--h1-margin-bottom: 1.5rem;
|
||||||
|
--h2-margin-top: 2rem;
|
||||||
|
--h2-margin-bottom: 1.5rem;
|
||||||
|
--hx-margin-top: 1.5rem;
|
||||||
|
--hx-margin-bottom: 1rem;
|
||||||
|
--p-margin-top: 1rem;
|
||||||
|
--p-margin-bottom: 1rem;
|
||||||
|
--code-margin-top: 2rem;
|
||||||
|
--code-margin-bottom: 2rem;
|
||||||
|
|
||||||
|
--h1-font-size: 2em;
|
||||||
|
--h2-font-size: 1.8em;
|
||||||
|
--hx-font-size: 1.3em;
|
||||||
|
--p-font-size: 1em;
|
||||||
|
--p-line-height: 1.5em;
|
||||||
|
--caption-font-size: .8em;
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
--li-indent: 2rem;
|
||||||
|
--ul-margin-top: 1rem;
|
||||||
|
--ul-margin-bottom: 1rem;
|
||||||
|
--li-checkbox-size: 0.8em;
|
||||||
|
|
||||||
|
/* TOC */
|
||||||
|
|
||||||
|
--toc-margin-top: 2rem;
|
||||||
|
--toc-margin-bottom: 3rem;
|
||||||
|
|
||||||
|
/* Code */
|
||||||
|
--code-padding: 1.5rem;
|
||||||
|
--code-border-radius: 10px;
|
||||||
|
--copy-code-button-border-radius: 7px;
|
||||||
|
|
||||||
|
/* Social section */
|
||||||
|
--social-icons-bottom-margin: 3rem;
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
--footer-height: 3rem;
|
||||||
|
|
||||||
|
/* Content */
|
||||||
|
--content-height: calc(100vh - var(--footer-height));
|
||||||
|
--figure-img-max-height: 800px;
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
--table-cell-padding: .5rem;
|
||||||
|
--table-margin-top: 1.5rem;
|
||||||
|
--table-margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) {
|
||||||
|
:root {
|
||||||
|
--main-width: 750px;
|
||||||
|
--header-top-gap: 1rem;
|
||||||
|
--caption-padding: calc(.25 * var(--main-padding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
:root {
|
||||||
|
--header-top-gap: 1rem;
|
||||||
|
--social-icons-bottom-margin: 0rem;
|
||||||
|
--caption-padding: calc(2 * var(--main-padding));
|
||||||
|
}
|
||||||
|
}
|
4
novemila/themes/typo/content/_index.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
+++
|
||||||
|
title = 'Home'
|
||||||
|
draft = false
|
||||||
|
+++
|
3
novemila/themes/typo/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module github.com/tomfran/typo
|
||||||
|
|
||||||
|
go 1.20
|
15
novemila/themes/typo/hugo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
baseURL = 'https://example.org/'
|
||||||
|
languageCode = 'en-us'
|
||||||
|
defaultContentLanguage = 'en-us'
|
||||||
|
title = 'typo'
|
||||||
|
|
||||||
|
[module]
|
||||||
|
[module.hugoVersion]
|
||||||
|
extended = false
|
||||||
|
min = "0.116.0"
|
||||||
|
|
||||||
|
# Default config
|
||||||
|
[params.breadcrumbs]
|
||||||
|
enabled = true
|
||||||
|
showCurrentPage = true
|
||||||
|
home = "Home"
|
BIN
novemila/themes/typo/images/1.webp
Normal file
After Width: | Height: | Size: 867 KiB |
BIN
novemila/themes/typo/images/2.webp
Normal file
After Width: | Height: | Size: 858 KiB |
BIN
novemila/themes/typo/images/3.webp
Normal file
After Width: | Height: | Size: 991 KiB |
BIN
novemila/themes/typo/images/banner-light.webp
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
novemila/themes/typo/images/screenshot.png
Normal file
After Width: | Height: | Size: 544 KiB |
BIN
novemila/themes/typo/images/tn.png
Normal file
After Width: | Height: | Size: 480 KiB |
12
novemila/themes/typo/layouts/404.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<div class="not-found">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1> typo? </h1>
|
||||||
|
<p> Click <a href="/">here</a> to return home </p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
@@ -0,0 +1,4 @@
|
|||||||
|
<pre class="mermaid">
|
||||||
|
{{- .Inner | htmlEscape | safeHTML }}
|
||||||
|
</pre>
|
||||||
|
{{ .Page.Store.Set "hasMermaid" true }}
|
@@ -0,0 +1,4 @@
|
|||||||
|
<h{{ .Level }} class="heading" id="{{ .Anchor }}">
|
||||||
|
{{ .Text }}
|
||||||
|
<a class="anchor" href="#{{ .Anchor }}">#</a>
|
||||||
|
</h{{ .Level }}>
|
@@ -0,0 +1,58 @@
|
|||||||
|
{{/*
|
||||||
|
To get page resources and relative paths to work. Copied as is from default
|
||||||
|
hook:
|
||||||
|
https://github.com/gohugoio/hugo/blob/89bd02/tpl/tplimpl/embedded/templates/_default/_markup/render-image.html
|
||||||
|
*/}}
|
||||||
|
{{- $u := urls.Parse .Destination -}}
|
||||||
|
{{- $url := $u.String -}}
|
||||||
|
{{- $imgResource := .Page.Scratch.Get "typoNilVariable" -}}
|
||||||
|
{{- if not $u.IsAbs -}}
|
||||||
|
{{- $path := strings.TrimPrefix "./" $u.Path -}}
|
||||||
|
{{/* Check if this is a page bundle or standalone page */}}
|
||||||
|
{{- if .PageInner.Resources -}}
|
||||||
|
{{- $imgResource = .PageInner.Resources.Get $path -}}
|
||||||
|
{{- else if (or .PageInner.Parent .PageInner.Parent.Resources) -}}
|
||||||
|
{{- $imgResource = .PageInner.Parent.Resources.Get $path -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $imgResource := or $imgResource (resources.Get $path) -}}
|
||||||
|
{{- with $imgResource -}}
|
||||||
|
{{- $url = .RelPermalink -}}
|
||||||
|
{{- with $u.RawQuery -}}
|
||||||
|
{{- $url = printf "%s?%s" $url . -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with $u.Fragment -}}
|
||||||
|
{{- $url = printf "%s#%s" $url . -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/* Split URL at # */}}
|
||||||
|
{{ $url = $url | safeURL }}
|
||||||
|
{{ $file_name_array := split $url "#" }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Iterate over all tags, which are in pos 1 to len array - 1,
|
||||||
|
and build the img class string as "img-tag1 img-tag2 ..."
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{ $classes := "" }}
|
||||||
|
|
||||||
|
{{ range $idx := seq (sub (len $file_name_array) 1) }}
|
||||||
|
{{ $tag := index $file_name_array $idx }}
|
||||||
|
{{ $classes = printf "%s img-%s" $classes $tag}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
|
{{/* Use the computed classes on the rendered figure */}}
|
||||||
|
<figure class="{{ $classes }}">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img loading="lazy" alt="{{ .Text }}" src="{{ $url }}" {{ with $imgResource }}width="{{ .Width }}px" height="{{ .Height }}px"{{ end }}>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ with .Title }}
|
||||||
|
<div class="caption-container">
|
||||||
|
<figcaption> {{ . | markdownify}} </figcaption>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</figure>
|
39
novemila/themes/typo/layouts/_default/baseof.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ or site.Language.LanguageCode site.Language.Lang }}"
|
||||||
|
dir="{{ or site.Language.LanguageDirection `ltr` }}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
{{ partial "head.html" . }}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
{{ $theme := "auto"}}
|
||||||
|
|
||||||
|
{{ with .Param "theme" }}
|
||||||
|
{{ $theme = .}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<body class="{{ $theme }}">
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<header>
|
||||||
|
{{ partial "header.html" . }}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main">
|
||||||
|
{{ block "main" . }}{{ end }}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{{ partial "footer.html" . }}
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
{{ if .Param "math" }}
|
||||||
|
{{ partialCached "math.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script src="{{ "js/theme-switch.js" | relURL }}"></script>
|
||||||
|
<script defer src="{{ "js/copy-code.js" | relURL }}"></script>
|
||||||
|
</html>
|
61
novemila/themes/typo/layouts/_default/home.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
{{ .Content }}
|
||||||
|
|
||||||
|
{{/* Intro summary section */}}
|
||||||
|
|
||||||
|
{{ if or .Site.Params.homeIntroTitle .Site.Params.homeIntroContent }}
|
||||||
|
<div class="intro">
|
||||||
|
{{ with .Site.Params.homeIntroTitle }}
|
||||||
|
<h1>{{ . }}</h1>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ with .Site.Params.homeIntroContent }}
|
||||||
|
<p>{{ . | markdownify }}</p>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Social Icons */}}
|
||||||
|
|
||||||
|
{{ with site.Params.social }}
|
||||||
|
<div class="social-icons">
|
||||||
|
{{- range . }}
|
||||||
|
<a href="{{ trim .url " " | safeURL }}" target="_blank"
|
||||||
|
rel="noopener noreferrer me"
|
||||||
|
title="{{ (.title | default .name) | title }}">
|
||||||
|
{{ partial "svg.html" . }}
|
||||||
|
</a>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Collection Section */}}
|
||||||
|
|
||||||
|
{{ if .Site.Params.homeCollection }}
|
||||||
|
|
||||||
|
<div class="list-container">
|
||||||
|
{{ with .Site.Params.homeCollectionTitle}}
|
||||||
|
<h1> {{ . }} </h1>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $pages := where .Site.RegularPages "Section" .Site.Params.homeCollection
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{ $paginationSize := 1}}
|
||||||
|
{{ if (gt .Site.Params.paginationSize 0) }}
|
||||||
|
{{ $paginationSize = .Site.Params.paginationSize }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $paginator := .Paginate $pages $paginationSize }}
|
||||||
|
|
||||||
|
{{ range $index, $page := $paginator.Pages }}
|
||||||
|
{{ partial "post-entry.html" $page}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ partial "pagination-controls.html" $paginator}}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
32
novemila/themes/typo/layouts/_default/list.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<div class="list-container">
|
||||||
|
|
||||||
|
{{ partial "breadcrumbs.html" . }}
|
||||||
|
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
{{ .Content }}
|
||||||
|
|
||||||
|
{{ $tagsPage := eq .Title "Tags"}}
|
||||||
|
|
||||||
|
{{ $paginationSize := 1}}
|
||||||
|
{{ if (gt .Site.Params.paginationSize 0) }}
|
||||||
|
{{ $paginationSize = .Site.Params.paginationSize }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ $paginator := .Paginate (.Pages) $paginationSize }}
|
||||||
|
|
||||||
|
{{ range $index, $page := $paginator.Pages }}
|
||||||
|
|
||||||
|
{{ if $tagsPage }}
|
||||||
|
{{ partial "tag-entry.html" $page}}
|
||||||
|
{{ else }}
|
||||||
|
{{ partial "post-entry.html" $page}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ partial "pagination-controls.html" $paginator}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
105
novemila/themes/typo/layouts/_default/single.html
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
{{/* Breadcrumbs */}}
|
||||||
|
|
||||||
|
{{ if not .IsHome }}
|
||||||
|
{{ partial "breadcrumbs.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<div {{ if .Param "autonumber" }} class="autonumber" {{ end }}>
|
||||||
|
|
||||||
|
<div class="single-intro-container">
|
||||||
|
|
||||||
|
{{/* Title and Summary */}}
|
||||||
|
|
||||||
|
<h1 class="single-title">{{ .Title }}</h1>
|
||||||
|
{{ with .Param "summary" }}
|
||||||
|
<p class="single-summary">{{ . | markdownify }}</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Reading Time */}}
|
||||||
|
|
||||||
|
<p class="single-readtime">
|
||||||
|
{{ with .Date }}
|
||||||
|
{{ $dateMachine := . | time.Format "2006-01-02T15:04:05-07:00" }}
|
||||||
|
{{ $dateHuman := . | time.Format (default ":date_long" $.Site.Params.singleDateFormat) }}
|
||||||
|
<time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{ if .Param "readTime" }}
|
||||||
|
·
|
||||||
|
{{ .ReadingTime }} min read
|
||||||
|
{{end }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ if .Param "showTags" }}
|
||||||
|
|
||||||
|
{{ $taxonomy := "tags" }}
|
||||||
|
{{ with .Param $taxonomy }}
|
||||||
|
|
||||||
|
<div class="single-tags">
|
||||||
|
{{ range $index, $tag := . }}
|
||||||
|
{{ with $.Site.GetPage (printf "/%s/%s" $taxonomy $tag) -}}
|
||||||
|
<span>
|
||||||
|
<a href="{{ .Permalink }}">#{{ .LinkTitle }}</a>
|
||||||
|
</span>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Table of Content */}}
|
||||||
|
|
||||||
|
{{ if .Param "toc" }}
|
||||||
|
<aside class="toc">
|
||||||
|
<p><strong>Table of contents</strong></p>
|
||||||
|
{{ .TableOfContents }}
|
||||||
|
</aside>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Page content */}}
|
||||||
|
|
||||||
|
<div class="single-content">
|
||||||
|
{{ .Content }}
|
||||||
|
{{ if .Site.Params.giscus.enable }}
|
||||||
|
{{ if not .Params.disableComment }}
|
||||||
|
{{ partial "comments.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ if .Store.Get "hasMermaid" }}
|
||||||
|
{{ $mermaidDarkTheme := default "dark" (or .Params.mermaidDarkTheme .Site.Params.mermaidDarkTheme) }}
|
||||||
|
{{ $mermaidTheme := default "default" (or .Params.mermaidTheme .Site.Params.mermaidTheme) }}
|
||||||
|
<script defer
|
||||||
|
type="module"
|
||||||
|
id="mermaid_script"
|
||||||
|
data-light-theme="{{ $mermaidTheme }}"
|
||||||
|
data-dark-theme="{{ $mermaidDarkTheme }}"
|
||||||
|
src='{{ "js/mermaid.js" | relURL }}'>
|
||||||
|
</script>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Next prev controls */}}
|
||||||
|
|
||||||
|
{{ if not (.Param "hidePagination") }}
|
||||||
|
{{ partial "pagination-single.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* Back to top */}}
|
||||||
|
|
||||||
|
{{ if not (.Param "hideBackToTop") }}
|
||||||
|
<div class="back-to-top">
|
||||||
|
<a href="#top">
|
||||||
|
back to top
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
23
novemila/themes/typo/layouts/partials/breadcrumbs.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{{- if .Site.Params.breadcrumbs.enabled -}}
|
||||||
|
{{- $breadcrumbs := .Site.Params.breadcrumbs -}}
|
||||||
|
<div class="breadcrumbs">
|
||||||
|
{{- range $i, $v := .Ancestors.Reverse -}}
|
||||||
|
<a href="{{ .RelPermalink }}">
|
||||||
|
{{- if (and (eq $i 0) (ne $breadcrumbs.home "")) -}}
|
||||||
|
{{- $breadcrumbs.home -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- .Title -}}
|
||||||
|
{{- end -}}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{{- if (lt $i (sub $.Ancestors.Len 1)) -}}
|
||||||
|
<span class="breadcrumbs-separator">/</span>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $breadcrumbs.showCurrentPage -}}
|
||||||
|
<span class="breadcrumbs-separator">/</span>
|
||||||
|
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
16
novemila/themes/typo/layouts/partials/comments.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script src="https://giscus.app/client.js"
|
||||||
|
data-repo="{{ .Site.Params.giscus.repo }}"
|
||||||
|
data-repo-id="{{ .Site.Params.giscus.repoid }}"
|
||||||
|
data-category="{{ .Site.Params.utteranc.category }}"
|
||||||
|
data-category-id="{{ .Site.Params.giscus.categoryid }}"
|
||||||
|
data-mapping="{{ .Site.Params.giscus.mapping }}"
|
||||||
|
data-strict="0"
|
||||||
|
data-reactions-enabled="1"
|
||||||
|
data-emit-metadata="0"
|
||||||
|
data-input-position="top"
|
||||||
|
data-theme="{{ .Site.Params.giscus.theme }}"
|
||||||
|
data-lang="en"
|
||||||
|
data-loading="lazy"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
async>
|
||||||
|
</script>
|
14
novemila/themes/typo/layouts/partials/footer.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{{ $showFooter := default true .Site.Params.showFooter }}
|
||||||
|
{{ if $showFooter }}
|
||||||
|
{{ if not .Site.Params.footerContent }}
|
||||||
|
<p>Powered by
|
||||||
|
<a href="https://gohugo.io/">Hugo</a>
|
||||||
|
and
|
||||||
|
<a href="https://github.com/tomfran/typo">tomfran/typo</a>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ with .Site.Params.footerContent }}
|
||||||
|
<p>{{ . | markdownify }}</p>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
48
novemila/themes/typo/layouts/partials/head.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
|
||||||
|
{{ $faviconPath := (.Site.Params.faviconPath | default "" | absURL) }}
|
||||||
|
|
||||||
|
<link rel="icon" type="image/ico" href="{{ $faviconPath }}/favicon.ico">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="{{ $faviconPath }}/favicon-16x16.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="{{ $faviconPath }}/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="192x192" href="{{ $faviconPath }}/android-chrome-192x192.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="{{ $faviconPath }}/apple-touch-icon.png">
|
||||||
|
|
||||||
|
{{ with .OutputFormats.Get "rss" -}}
|
||||||
|
{{ printf `<link rel=%q type=%q href=%q title=%q>` .Rel .MediaType.Type .Permalink site.Title | safeHTML }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if .IsHome -}}
|
||||||
|
<meta name="description" content="{{ site.Params.Description }}"/>
|
||||||
|
{{- else -}}
|
||||||
|
<meta name="description" content="{{ .Params.Description }}"/>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ if .Param "fediverse" }}
|
||||||
|
<meta name="fediverse:creator" content="{{ .Params.Fediverse }}">
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<title>
|
||||||
|
{{ if .IsHome }}
|
||||||
|
{{ site.Title }}
|
||||||
|
{{ else }}
|
||||||
|
{{ printf "%s | %s" .Title site.Title }}
|
||||||
|
{{ end }}
|
||||||
|
</title>
|
||||||
|
|
||||||
|
<link rel="canonical" href="{{ .Permalink }}"/>
|
||||||
|
|
||||||
|
{{ template "_internal/opengraph.html" . }}
|
||||||
|
|
||||||
|
{{ partialCached "head/css.html" . }}
|
||||||
|
{{ partialCached "head/js.html" . }}
|
||||||
|
|
||||||
|
{{ if hugo.IsProduction }}
|
||||||
|
{{ template "_internal/google_analytics.html" . }}
|
||||||
|
|
||||||
|
{{ if .Site.Params.umami.enable }}
|
||||||
|
{{ partial "umami.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
26
novemila/themes/typo/layouts/partials/head/css.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{{
|
||||||
|
$CSS := slice
|
||||||
|
(resources.Get "css/reset.css")
|
||||||
|
(resources.Get "css/vars.css")
|
||||||
|
(resources.Get "css/utils.css")
|
||||||
|
(resources.Get "css/fonts.css")
|
||||||
|
(resources.Get "css/main.css")
|
||||||
|
(resources.Get "css/custom.css")
|
||||||
|
(resources.Get "css/colors/default.css")
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{ with .Site.Params.colorPalette }}
|
||||||
|
|
||||||
|
{{ $path := printf "css/colors/%s.css" . }}
|
||||||
|
{{ $CSS = $CSS | append (resources.Get $path)}}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{
|
||||||
|
$combined := $CSS
|
||||||
|
| resources.Concat "assets/combined.css"
|
||||||
|
| minify
|
||||||
|
| fingerprint
|
||||||
|
}}
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ $combined.RelPermalink }}" media="all">
|
7
novemila/themes/typo/layouts/partials/head/js.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{{- with resources.Get "js/main.js" }}
|
||||||
|
{{- $opts := dict "minify" true }}
|
||||||
|
{{- with . | js.Build $opts | fingerprint }}
|
||||||
|
<script src="{{ .RelPermalink }}" integrity="{{- .Data.Integrity }}"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
28
novemila/themes/typo/layouts/partials/header.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{{/* Header */}}
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
|
||||||
|
{{ if or (not (.Param "hideHeader")) .IsHome }}
|
||||||
|
|
||||||
|
<h1 class="header-title">
|
||||||
|
<a href="{{ site.BaseURL }}">{{ site.Title }}</a>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
{{ $currentPage := . }}
|
||||||
|
|
||||||
|
{{ with site.Params.menu }}
|
||||||
|
{{ range . }}
|
||||||
|
|
||||||
|
<p class="small {{ if eq .name (lower $currentPage.Name) }} bold {{end}}">
|
||||||
|
<a href="{{ .url }}" {{ if and (isset . "newTab") .newTab }}target="_blank" rel="noopener noreferrer"{{ end }}>
|
||||||
|
/{{.name }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
19
novemila/themes/typo/layouts/partials/math.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css">
|
||||||
|
<script defer
|
||||||
|
src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js"></script>
|
||||||
|
|
||||||
|
<script defer
|
||||||
|
src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js"
|
||||||
|
onload="renderMathInElement(document.body);"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
delimiters: [
|
||||||
|
{ left: "$$", right: "$$", display: true },
|
||||||
|
{ left: "$", right: "$", display: false }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
@@ -0,0 +1,23 @@
|
|||||||
|
{{ if gt .TotalPages 1 }}
|
||||||
|
<div class="pagination">
|
||||||
|
<div class="pagination-control">
|
||||||
|
{{ if .HasPrev }}
|
||||||
|
<a href="{{ .Prev.URL | absURL }}">
|
||||||
|
prev
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div class="page-number">
|
||||||
|
<p>
|
||||||
|
{{ .PageNumber }}/{{ .TotalPages }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="pagination-control">
|
||||||
|
{{ if .HasNext }}
|
||||||
|
<a href="{{ .Next.URL | absURL }}">
|
||||||
|
next
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
39
novemila/themes/typo/layouts/partials/pagination-single.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{{ if or .NextInSection .PrevInSection }}
|
||||||
|
|
||||||
|
<div class="single-pagination">
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
|
||||||
|
<div class="single-pagination-prev">
|
||||||
|
{{ with .PrevInSection }}
|
||||||
|
<div class="single-pagination-container-prev">
|
||||||
|
<div class="single-pagination-text">←</div>
|
||||||
|
<div class="single-pagination-text">
|
||||||
|
<a href="{{ .RelPermalink }}">
|
||||||
|
{{ .Title }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="single-pagination-next">
|
||||||
|
{{ with .NextInSection }}
|
||||||
|
<div class="single-pagination-container-next">
|
||||||
|
<div class="single-pagination-text">
|
||||||
|
<a href="{{ .RelPermalink }}">
|
||||||
|
{{ .Title }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="single-pagination-text">→</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
21
novemila/themes/typo/layouts/partials/post-entry.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<div class="post-line">
|
||||||
|
|
||||||
|
{{ $dateFormat := "2 Jan 2006"}}
|
||||||
|
{{ with .Site.Params.listDateFormat }}
|
||||||
|
{{ $dateFormat = .}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<p class="line-date">{{ .Date | time.Format $dateFormat }} </p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p class="line-title">
|
||||||
|
<a href="{{ .RelPermalink }}">
|
||||||
|
{{ .Title }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{ if .Site.Params.listSummaries }}
|
||||||
|
<p class="line-summary"> {{ .Summary }} </p>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
6562
novemila/themes/typo/layouts/partials/svg.html
Normal file
7
novemila/themes/typo/layouts/partials/tag-entry.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="tag-line">
|
||||||
|
<div>
|
||||||
|
<p class="tag-title">
|
||||||
|
<a href="{{ .RelPermalink }}">#{{ .Title }}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
6
novemila/themes/typo/layouts/partials/umami.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<script
|
||||||
|
async
|
||||||
|
defer
|
||||||
|
data-website-id="{{ .Site.Params.umami.websiteId }}"
|
||||||
|
src="{{ .Site.Params.umami.jsLocation }}"
|
||||||
|
></script>
|
BIN
novemila/themes/typo/static/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
novemila/themes/typo/static/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
novemila/themes/typo/static/favicon-16x16.png
Normal file
After Width: | Height: | Size: 582 B |
BIN
novemila/themes/typo/static/favicon-32x32.png
Normal file
After Width: | Height: | Size: 665 B |
BIN
novemila/themes/typo/static/favicon.ico
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
novemila/themes/typo/static/fonts/Literata/Literata-Light.woff2
Normal file
34
novemila/themes/typo/static/js/copy-code.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const codeBlocks = document.querySelectorAll("pre");
|
||||||
|
|
||||||
|
codeBlocks.forEach((codeBlock) => {
|
||||||
|
if (codeBlock.className == "mermaid") return;
|
||||||
|
const copyButton = document.createElement("button");
|
||||||
|
copyButton.className = "copy-code-button";
|
||||||
|
copyButton.textContent = "copy";
|
||||||
|
|
||||||
|
// Insert the button inside the <pre> block
|
||||||
|
codeBlock.appendChild(copyButton);
|
||||||
|
|
||||||
|
copyButton.addEventListener("click", function () {
|
||||||
|
const code = codeBlock.querySelector("code");
|
||||||
|
// Get the code content
|
||||||
|
const textToCopy = code.textContent || code.innerText;
|
||||||
|
|
||||||
|
// Use the Clipboard API to copy the text
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(textToCopy)
|
||||||
|
.then(() => {
|
||||||
|
// Change button text to "Copied"
|
||||||
|
copyButton.textContent = "copied";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
copyButton.textContent = "copy";
|
||||||
|
}, 2000); // Reset the button text after 2 seconds
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("Unable to copy text:", err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
28
novemila/themes/typo/static/js/mermaid.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
|
||||||
|
|
||||||
|
const this_js_script = document.getElementById('mermaid_script');
|
||||||
|
const light_theme = this_js_script.getAttribute('data-light-theme');
|
||||||
|
const dark_theme = this_js_script.getAttribute('data-dark-theme');
|
||||||
|
|
||||||
|
function runmermaid() {
|
||||||
|
const theme = (document.body.classList.contains('dark') ? dark_theme : light_theme)
|
||||||
|
mermaid.initialize({ startOnLoad: false, theme: theme});
|
||||||
|
const items = document.querySelectorAll('.mermaid');
|
||||||
|
let counter = 0;
|
||||||
|
for (const item of items) {
|
||||||
|
const id = counter++;
|
||||||
|
if(item.originalCode === undefined) {
|
||||||
|
item.originalCode = item.textContent.trim();
|
||||||
|
}
|
||||||
|
mermaid.render("mermaid"+id, item.originalCode).then((val) => {
|
||||||
|
item.innerHTML = val.svg
|
||||||
|
}, (err) => {
|
||||||
|
console.log(err);
|
||||||
|
// Workaround: move incorrectly placed error messages into their diagram
|
||||||
|
item.innerHTML = "";
|
||||||
|
item.appendChild(document.getElementById("mermaid" + id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', runmermaid);
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', runmermaid);
|
28
novemila/themes/typo/static/js/theme-switch.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
function isAuto() {
|
||||||
|
return document.body.classList.contains("auto");
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTheme() {
|
||||||
|
if (!isAuto()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.classList.remove("auto");
|
||||||
|
let cls = "light";
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
cls = "dark";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.classList.add(cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
function invertBody() {
|
||||||
|
document.body.classList.toggle("dark");
|
||||||
|
document.body.classList.toggle("light");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAuto()) {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addListener(invertBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme();
|
36
novemila/themes/typo/theme.toml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name = 'Typo'
|
||||||
|
license = 'MIT'
|
||||||
|
licenselink = 'https://github.com/tomfran/typo/blob/main/LICENSE'
|
||||||
|
description = 'A simple Hugo theme'
|
||||||
|
|
||||||
|
homepage = 'https://github.com/tomfran/typo'
|
||||||
|
|
||||||
|
demosite = 'https://tomfran.github.io/'
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"responsive",
|
||||||
|
"simple",
|
||||||
|
"clean",
|
||||||
|
"light",
|
||||||
|
"dark",
|
||||||
|
"blog",
|
||||||
|
"minimal",
|
||||||
|
"personal",
|
||||||
|
"portfolio",
|
||||||
|
]
|
||||||
|
|
||||||
|
features = [
|
||||||
|
"responsive",
|
||||||
|
"blog",
|
||||||
|
"table-of-contents",
|
||||||
|
"highlight.js",
|
||||||
|
"favicon",
|
||||||
|
"social-icons",
|
||||||
|
"minified-assets",
|
||||||
|
"dark-light-images",
|
||||||
|
"color-palettes",
|
||||||
|
]
|
||||||
|
|
||||||
|
[author]
|
||||||
|
name = 'Francesco Tomaselli'
|
||||||
|
homepage = 'https://tomfran.github.io/'
|
88
novemila/themes/typo/wiki/contributors.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
title: "Contributors"
|
||||||
|
date: "2025-01-01"
|
||||||
|
summary: "List of Typo's contributors"
|
||||||
|
description: "List of Typo's contributors"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: false
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
hidePagination: true
|
||||||
|
hideBackToTop: false
|
||||||
|
---
|
||||||
|
|
||||||
|
<div id="loading-message">Fetching GitHub data, hang tight!</div>
|
||||||
|
|
||||||
|
<div id="content" style="display: none;">
|
||||||
|
The theme has accumulated <span id="star-count">over 300</span> stars on Github, and
|
||||||
|
currently counts <span id="contributors-count">over 20</span> contributors:
|
||||||
|
|
||||||
|
<ul id="contributors-list" style="list-style-type: none; padding: 0; margin-top: 2rem"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function fetchGitHubData() {
|
||||||
|
const cacheKey = "githubData";
|
||||||
|
const cacheExpiryKey = "githubDataExpiry";
|
||||||
|
const cacheExpiryTime = 3600 * 1000; // 1 hour in milliseconds
|
||||||
|
|
||||||
|
// Check if cached data exists and is still valid
|
||||||
|
const cachedData = localStorage.getItem(cacheKey);
|
||||||
|
const cachedExpiry = localStorage.getItem(cacheExpiryKey);
|
||||||
|
const now = new Date().getTime();
|
||||||
|
|
||||||
|
if (cachedData && cachedExpiry && now < cachedExpiry) {
|
||||||
|
const { starCount, contributors } = JSON.parse(cachedData);
|
||||||
|
updateUI(starCount, contributors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch star count
|
||||||
|
const repoResponse = await fetch("https://api.github.com/repos/tomfran/typo");
|
||||||
|
const repoData = await repoResponse.json();
|
||||||
|
const starCount = repoData.stargazers_count;
|
||||||
|
|
||||||
|
// Fetch contributors
|
||||||
|
const contributorsResponse = await fetch("https://api.github.com/repos/tomfran/typo/contributors");
|
||||||
|
const contributors = await contributorsResponse.json();
|
||||||
|
|
||||||
|
// Cache data
|
||||||
|
localStorage.setItem(cacheKey, JSON.stringify({ starCount, contributors }));
|
||||||
|
localStorage.setItem(cacheExpiryKey, now + cacheExpiryTime);
|
||||||
|
|
||||||
|
updateUI(starCount, contributors);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching GitHub data:", error);
|
||||||
|
document.getElementById("star-count").textContent = "Failed to fetch star count.";
|
||||||
|
document.getElementById("contributors-count").textContent = "Failed to fetch contributors count.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateUI(starCount, contributors) {
|
||||||
|
document.getElementById("loading-message").style.display = "none";
|
||||||
|
document.getElementById("content").style.display = "block";
|
||||||
|
|
||||||
|
document.getElementById("star-count").textContent = `${starCount}`;
|
||||||
|
document.getElementById("contributors-count").textContent = `${contributors.length}`;
|
||||||
|
|
||||||
|
const contributorsList = document.getElementById("contributors-list");
|
||||||
|
contributorsList.innerHTML = "";
|
||||||
|
|
||||||
|
contributors.forEach(contributor => {
|
||||||
|
const listItem = document.createElement("li");
|
||||||
|
listItem.style.marginBottom = ".5rem";
|
||||||
|
listItem.innerHTML = `
|
||||||
|
<span style="display: flex; align-items: bottom;">
|
||||||
|
<img src="${contributor.avatar_url}" alt="${contributor.login}" width="30" height="30" style="margin-right: 10px; border-radius: 50%;">
|
||||||
|
<a href="${contributor.html_url}">${contributor.login}</a> - ${contributor.contributions}
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
contributorsList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchGitHubData();
|
||||||
|
</script>
|
97
novemila/themes/typo/wiki/features/appearance.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
title: "Appearance"
|
||||||
|
date: "2024-10-12"
|
||||||
|
summary: "Appearance parameters"
|
||||||
|
description: "Appearance parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Typo has a built-in dark and light mode, you can decide the default one and control images on both modes.
|
||||||
|
|
||||||
|
## Choosing a Theme
|
||||||
|
|
||||||
|
By default the mode in use is auto, if you want, you can hard-code a color scheme.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
theme = 'auto | light | dark'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Choosing a Color Palette
|
||||||
|
|
||||||
|
Typo has the possibility to specify the color palette to use in the theme. The default one is black and white,
|
||||||
|
but they can easily be added.
|
||||||
|
|
||||||
|
The color palettes are stored under `assets/css/colors/*` and the one in use can be specified with the following
|
||||||
|
parameter:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
colorPalette = 'default'
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that omitting the parameter implies using the default palette.
|
||||||
|
|
||||||
|
This is the complete list of palettes available:
|
||||||
|
- default;
|
||||||
|
- catpuccin;
|
||||||
|
- gruvebox;
|
||||||
|
- eink;
|
||||||
|
- base16-default;
|
||||||
|
- base16-eighties;
|
||||||
|
- base16-ocean;
|
||||||
|
- base16-mocha;
|
||||||
|
- base16-cupcake.
|
||||||
|
|
||||||
|
More are to come.
|
||||||
|
|
||||||
|
## Adding a Custom Color Palette
|
||||||
|
|
||||||
|
You can add a custom color palette by creating a new file under `assets/css/colors/*` named after your wanted palette name.
|
||||||
|
Use another one as base and define the required parameters.
|
||||||
|
|
||||||
|
You can then use your new palette, by using its file name in the `colorPalette` site param.
|
||||||
|
|
||||||
|
## Hide Header Mode
|
||||||
|
|
||||||
|
You can choose to hide the header on every page apart from the homepage with this parameter.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
hideHeader = true
|
||||||
|
```
|
||||||
|
|
||||||
|
I strongly recommend enabling breadcrumbs if you do so.
|
||||||
|
|
||||||
|
## Note on Syntax Highlighting
|
||||||
|
|
||||||
|
The theme supports syntax highlighting, and you can specify the theme as follows:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[markup]
|
||||||
|
[markup.highlight]
|
||||||
|
style = 'algol'
|
||||||
|
```
|
||||||
|
|
||||||
|
`algol` is the recommended theme, and for it to work, the background-color of the code
|
||||||
|
elements is enforced.
|
||||||
|
This has the side effect of breaking other color schemes, e.g. Monokai.
|
||||||
|
|
||||||
|
You can make them work by removing `!important` from the background color of the code pre elements.
|
||||||
|
|
||||||
|
I suggest trying [color schemes](https://xyproto.github.io/splash/docs/all.html) and see what can work for you.
|
||||||
|
|
||||||
|
## Footer Customization
|
||||||
|
|
||||||
|
One can decide to hide the footer completely or to change it's content by specifying the following parameters.
|
||||||
|
Note that if you don't include the following parameters (or leave footerContent empty) the default footer is shown.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
showFooter = true
|
||||||
|
footerContent = "Your **custom** md `footer`"
|
||||||
|
```
|
40
novemila/themes/typo/wiki/features/collections.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
title: "Collections"
|
||||||
|
date: "2024-10-10"
|
||||||
|
summary: "Collections parameters"
|
||||||
|
description: "Collections parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Here are some parameters regarding collections, those apply to both the home displayed one and to the dedicated folder pages.
|
||||||
|
|
||||||
|
## Pagination
|
||||||
|
|
||||||
|
Specify the maximum number of posts per page.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
paginationSize = 100
|
||||||
|
```
|
||||||
|
|
||||||
|
## Date Format
|
||||||
|
|
||||||
|
The date format can be tweaked with a format string.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
listDateFormat = '2 Jan 2006'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary Toggle
|
||||||
|
|
||||||
|
Summaries can be turned on and off with this setting.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
listSummaries = true
|
||||||
|
```
|
54
novemila/themes/typo/wiki/features/controlling-images.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
title: "Controlling Images"
|
||||||
|
date: "2024-10-11"
|
||||||
|
summary: "Controlling Images parameters"
|
||||||
|
description: "Controlling Images parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dark and Light Mode Images
|
||||||
|
|
||||||
|
Sometimes images don't look good in both light and dark mode. You can annotate the import path with a special tag to ensure an image is only shown on a specific color scheme.
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
In the above example, the light image is a transparent background with dark lines, while the dark one has light ones.
|
||||||
|
|
||||||
|
If you omit the `#dark` or `#light` tags an image is always shown.
|
||||||
|
|
||||||
|
## Images Sizing
|
||||||
|
|
||||||
|
There exist two tags to control sizing:
|
||||||
|
- `#small`: the image takes 80% of the original scale.
|
||||||
|
- `#full`: the image takes up all the available screen width.
|
||||||
|
|
||||||
|
You can also specify a caption using the following form:
|
||||||
|
|
||||||
|
```
|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
I understand everyone could want a different scale for small images, you can override the default small class in your custom CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.img-small img {
|
||||||
|
scale: 80%;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[Here](https://tomfran.github.io/posts/hugo-images/) you can find a blog post showing different tags combinations.
|
||||||
|
|
||||||
|
## Adding new Image Tags
|
||||||
|
|
||||||
|
All tags are assumed to be related to an image class, which applies styling for the figure environment.
|
||||||
|
|
||||||
|
You can add a new one, provided you add a class named `img-<tag_name>`.
|
||||||
|
|
||||||
|
Feel free to have a look at existing ones to have a grasp on how they work.
|
27
novemila/themes/typo/wiki/features/custom-css.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: "Custom CSS"
|
||||||
|
date: "2024-10-07"
|
||||||
|
summary: "Custom CSS parameters"
|
||||||
|
description: "Custom CSS parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
hideBackToTop: true
|
||||||
|
---
|
||||||
|
|
||||||
|
The theme supports custom css, you can override anything you want by redefining classes in the `assets/css/custom.css` file.
|
||||||
|
|
||||||
|
For instance, changing the main width can be done as follows:
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--main-width: 1024px; /* overrides default of 780px */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that backward incompatible changes in the CSS will likely not happen, but there might be cases in the future where
|
||||||
|
backward compatibility is not possible. If you are overriding a huge amount of CSS I suggest you forking the project instead of
|
||||||
|
defining it here.
|
||||||
|
|
32
novemila/themes/typo/wiki/features/header.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: "Header"
|
||||||
|
date: "2024-10-13"
|
||||||
|
summary: "Header parameters"
|
||||||
|
description: "Header parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
To pick pages to include in the header you must add the following elements:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[params.menu]]
|
||||||
|
name = "home"
|
||||||
|
url = "/"
|
||||||
|
|
||||||
|
[[params.menu]]
|
||||||
|
name = "posts"
|
||||||
|
url = "/posts"
|
||||||
|
```
|
||||||
|
|
||||||
|
There exists an optional new tab parameter, to choose whether menu items are opened in a new tab or not.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[params.menu]]
|
||||||
|
name = "posts"
|
||||||
|
url = "/posts"
|
||||||
|
newTab = true
|
||||||
|
```
|
56
novemila/themes/typo/wiki/features/homepage.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
title: "Homepage"
|
||||||
|
date: "2024-10-14"
|
||||||
|
summary: "Homepage parameters"
|
||||||
|
description: "Homepage parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
The homepage offers minimal customization options, you can specify an intro, a collection to display, and social icons.
|
||||||
|
|
||||||
|
## Intro Section
|
||||||
|
|
||||||
|
By setting those two parameters in your `hugo.toml` config you can control the text to display after the header on the homepage. Note that the body is interpreted as markdown.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
homeIntroTitle = 'Hi!'
|
||||||
|
|
||||||
|
homeIntroContent = """
|
||||||
|
I am an Italian Software Engineer with a strong foundation in computer science and a passion for solving complex problems.
|
||||||
|
I am interested in a range of topics, including algorithms, distributed systems, databases, and information retrieval.
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that you can omit one of the two if you want.
|
||||||
|
|
||||||
|
## Social Icons
|
||||||
|
|
||||||
|
You can include social icons after the intro like follows.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[params.social]]
|
||||||
|
name = "linkedin"
|
||||||
|
url = "https://www.linkedin.com/in/user/"
|
||||||
|
|
||||||
|
[[params.social]]
|
||||||
|
name = "medium"
|
||||||
|
url = "https://medium.com/@user"
|
||||||
|
```
|
||||||
|
|
||||||
|
If some icons are missing, feel free to open a request or a PR.
|
||||||
|
## Display a Collection
|
||||||
|
|
||||||
|
You can decide to include a collection in your homepage:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
homeCollectionTitle = 'Posts'
|
||||||
|
homeCollection = 'posts'
|
||||||
|
```
|
||||||
|
|
||||||
|
The above example includes the `/posts` collection. Note that you can omit the title if you prefer.
|
108
novemila/themes/typo/wiki/features/other-parameters.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
title: "Other Parameters"
|
||||||
|
date: "2024-10-08"
|
||||||
|
summary: "Other Parameters parameters"
|
||||||
|
description: "Other Parameters parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Miscellaneous settings.
|
||||||
|
|
||||||
|
## Home Meta Description
|
||||||
|
|
||||||
|
You can specify the homepage meta description with the following parameter:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
description = "Your description"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Breadcrumbs
|
||||||
|
|
||||||
|
Show breadcrumbs on pages.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params.breadcrumbs]
|
||||||
|
enabled = true
|
||||||
|
showCurrentPage = true
|
||||||
|
home = "~"
|
||||||
|
```
|
||||||
|
|
||||||
|
Set `enabled` to `false` if you want to hide breadcrumbs. By default, breadcrumbs are shown.
|
||||||
|
|
||||||
|
Set `showCurrentPage` to `false` to hide the last crumb, i.e, the current page.
|
||||||
|
|
||||||
|
`home` when set with a non-empty string, uses the latter as the first crumb instead of the string "Home".
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
Enable comments on your posts using [Giscus](https://giscus.app/).
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params.giscus]
|
||||||
|
enable = false
|
||||||
|
repo = "your/repo"
|
||||||
|
repoid = "id"
|
||||||
|
category = "category"
|
||||||
|
categoryid = "categoryId"
|
||||||
|
mapping = "pathname"
|
||||||
|
theme = "preferred_color_scheme"
|
||||||
|
```
|
||||||
|
|
||||||
|
Tip: use `preferred_color_scheme` theme to have a consistent dark and light appearance.
|
||||||
|
|
||||||
|
You can decide to hide the comments section on certain pages, using the following parameter on the page itself:
|
||||||
|
|
||||||
|
```md
|
||||||
|
disableComment: true
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Umami
|
||||||
|
|
||||||
|
You can include [Umami](https://umami.is/) in your website as follows:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params.umami]
|
||||||
|
enable = true
|
||||||
|
websiteId = "unique-website-id"
|
||||||
|
jsLocation = "http://example.org/umami.js"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Favicons
|
||||||
|
|
||||||
|
The following favicons are included in the head of the website:
|
||||||
|
- `favicon.ico`
|
||||||
|
- `favicon-16x16.png`
|
||||||
|
- `favicon-32x32.png`
|
||||||
|
- `android-chrome-192x192.png`
|
||||||
|
- `apple-touch-icon.png`
|
||||||
|
|
||||||
|
You must override the existing one in your static folder.
|
||||||
|
|
||||||
|
You can also specify a subdirectory of /static if you prefer
|
||||||
|
using the following param:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
faviconPath = 'your-path'
|
||||||
|
```
|
||||||
|
|
||||||
|
You can easily generate favicons using [this website](https://realfavicongenerator.net/) starting from your image.
|
||||||
|
[Here](https://github.com/tomfran/tomfran.github.io/tree/main/static) you can see an example of icons overriding default ones.
|
||||||
|
|
||||||
|
## Mermaid Diagrams
|
||||||
|
|
||||||
|
Mermaid diagrams are supported, just follow [this reference](https://gohugo.io/content-management/diagrams/#mermaid-diagrams) to use them. You can set Mermaid's light- and dark themes in your config; they switch with your blog's light/dark state. These are the defaults:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
mermaidTheme = "default"
|
||||||
|
mermaidDarkTheme = "dark"
|
||||||
|
```
|
97
novemila/themes/typo/wiki/features/single-page-parameters.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
title: "Single Page Parameters"
|
||||||
|
date: "2024-10-09"
|
||||||
|
summary: "Single Page Parameters parameters"
|
||||||
|
description: "Single Page Parameters parameters"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
---
|
||||||
|
|
||||||
|
The following parameters apply to single pages, they are meant to be inserted in the `.md` files introductions, apart from the date format.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
Show a table of contents at the beginning of the post.
|
||||||
|
|
||||||
|
```md
|
||||||
|
toc: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sections Auto-numbering
|
||||||
|
|
||||||
|
Auto-number headings.
|
||||||
|
|
||||||
|
```md
|
||||||
|
autonumber: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that headings should start from level two.
|
||||||
|
|
||||||
|
## Math Rendering
|
||||||
|
|
||||||
|
Enable math rendering.
|
||||||
|
|
||||||
|
```md
|
||||||
|
math: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
|
||||||
|
Create tags associated with the post and decide to show them.
|
||||||
|
|
||||||
|
```md
|
||||||
|
tags: ["database", "java"]
|
||||||
|
showTags: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Display Read Time
|
||||||
|
|
||||||
|
Choose to display reading time.
|
||||||
|
|
||||||
|
```md
|
||||||
|
readTime: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hide Back to Top
|
||||||
|
|
||||||
|
Choose to display back to top at the end of the page.
|
||||||
|
|
||||||
|
```md
|
||||||
|
hideBackToTop: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hide Pagination Controls
|
||||||
|
|
||||||
|
Choose to display pagination controls at the end of the page.
|
||||||
|
|
||||||
|
```md
|
||||||
|
hidePagination: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Meta Description
|
||||||
|
|
||||||
|
You can specify the post meta description as follows:
|
||||||
|
|
||||||
|
```md
|
||||||
|
description: "Your Description"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fediverse
|
||||||
|
|
||||||
|
You can include a [fediverse handle](https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/) in your posts.
|
||||||
|
|
||||||
|
```md
|
||||||
|
fediverse: "@username@instance.url"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Date Format
|
||||||
|
|
||||||
|
You can decide the date format to apply to single posts by setting the following param in the toml file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[params]
|
||||||
|
singleDateFormat = '2 January 2006'
|
||||||
|
```
|
188
novemila/themes/typo/wiki/setup.md
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
---
|
||||||
|
title: "Setup"
|
||||||
|
date: "2024-10-12"
|
||||||
|
summary: "How to setup a Hugo's website using Typo as a theme."
|
||||||
|
description: "Getting started with Typo theme"
|
||||||
|
toc: false
|
||||||
|
readTime: false
|
||||||
|
autonumber: true
|
||||||
|
math: false
|
||||||
|
showTags: false
|
||||||
|
hidePagination: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Below are the ways to get started with the Typo theme.
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
|
First of all, create a new Hugo project as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hugo new site <your site name> --config toml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Downloading the Theme
|
||||||
|
|
||||||
|
Themes are contained in the `/themes` directory, there are different ways to get Typo there
|
||||||
|
|
||||||
|
**Submodule - Recommended**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule add --depth=1 https://github.com/tomfran/typo.git themes/typo
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
**Hugo module**
|
||||||
|
|
||||||
|
Installing Typo as a Hugo module requires Go to be installed in your development environment.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize your project as a Hugo module
|
||||||
|
hugo mod init <module_name>
|
||||||
|
# Install the theme
|
||||||
|
hugo mod get github.com/tomfran/typo
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add the following to `hugo.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[module]
|
||||||
|
[[module.imports]]
|
||||||
|
path = "github.com/tomfran/typo"
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, remove the `theme = 'typo'` parameter from `hugo.toml`.
|
||||||
|
|
||||||
|
**Cloning**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/tomfran/typo themes/typo --depth=1
|
||||||
|
```
|
||||||
|
|
||||||
|
You need to keep it updated manually by pulling.
|
||||||
|
|
||||||
|
**Manual download a release**
|
||||||
|
|
||||||
|
Finally, you can manually download a [release](https://github.com/tomfran/typo/releases) and unzip it into the appropriate folder.
|
||||||
|
|
||||||
|
## Sample Config
|
||||||
|
|
||||||
|
Use those to get started with the theme. You can find a complete overview of the available features [here](https://tomfran.github.io/typo-wiki/features/).
|
||||||
|
|
||||||
|
[Here](https://github.com/tomfran/tomfran.github.io) you can find a repo using this theme.
|
||||||
|
|
||||||
|
### Site Config
|
||||||
|
|
||||||
|
Here is a sample `hugo.toml` config to get started with the theme.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
baseURL = 'https://example.org/'
|
||||||
|
languageCode = 'en-us'
|
||||||
|
title = 'My website'
|
||||||
|
theme = 'typo'
|
||||||
|
|
||||||
|
# Google analytics code
|
||||||
|
googleAnalytics = "G-xxxxxxxxx"
|
||||||
|
|
||||||
|
[taxonomies]
|
||||||
|
tag = 'tags'
|
||||||
|
|
||||||
|
[params]
|
||||||
|
# Meta description
|
||||||
|
description = "A Tech Blog"
|
||||||
|
|
||||||
|
# Appearance settings
|
||||||
|
theme = 'auto'
|
||||||
|
colorPalette = 'default'
|
||||||
|
hideHeader = false
|
||||||
|
|
||||||
|
# Intro on main page, content is markdown
|
||||||
|
homeIntroTitle = 'Hi!'
|
||||||
|
homeIntroContent = """
|
||||||
|
I am an Italian Software Engineer with a strong foundation in computer science and a passion for solving complex problems.
|
||||||
|
I am interested in a range of topics, including algorithms, distributed systems, databases, and information retrieval.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Collection to display on home
|
||||||
|
homeCollectionTitle = 'Posts'
|
||||||
|
homeCollection = 'posts'
|
||||||
|
|
||||||
|
# Lists parameters
|
||||||
|
paginationSize = 100
|
||||||
|
listSummaries = true
|
||||||
|
listDateFormat = '2 Jan 2006'
|
||||||
|
|
||||||
|
# Breadcrumbs
|
||||||
|
[params.breadcrumbs]
|
||||||
|
enabled = true
|
||||||
|
showCurrentPage = true
|
||||||
|
home = "Home"
|
||||||
|
|
||||||
|
# Social icons
|
||||||
|
[[params.social]]
|
||||||
|
name = "linkedin"
|
||||||
|
url = "https://www.linkedin.com/in/user/"
|
||||||
|
|
||||||
|
[[params.social]]
|
||||||
|
name = "medium"
|
||||||
|
url = "https://medium.com/@user"
|
||||||
|
|
||||||
|
[[params.social]]
|
||||||
|
name = "github"
|
||||||
|
url = "https://github.com/user"
|
||||||
|
|
||||||
|
# Main menu pages
|
||||||
|
[[params.menu]]
|
||||||
|
name = "home"
|
||||||
|
url = "/"
|
||||||
|
|
||||||
|
[[params.menu]]
|
||||||
|
name = "posts"
|
||||||
|
url = "/posts"
|
||||||
|
|
||||||
|
[[params.menu]]
|
||||||
|
name = "about"
|
||||||
|
url = "/about"
|
||||||
|
|
||||||
|
# Syntax highlight on code blocks
|
||||||
|
[markup]
|
||||||
|
[markup.highlight]
|
||||||
|
style = 'algol'
|
||||||
|
|
||||||
|
# Giscus comments
|
||||||
|
[params.giscus]
|
||||||
|
enable = false
|
||||||
|
repo = "user/repo"
|
||||||
|
repoid = "repoId"
|
||||||
|
category = "General"
|
||||||
|
categoryid = "categoryId"
|
||||||
|
mapping = "pathname"
|
||||||
|
theme = "preferred_color_scheme"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Post Config
|
||||||
|
|
||||||
|
Sample post config.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: "Log-Structured Merge Tree"
|
||||||
|
date: "2023-11-12"
|
||||||
|
summary: "An LSM Tree overview and Java implementation."
|
||||||
|
description: "An LSM Tree overview and Java implementation."
|
||||||
|
toc: true
|
||||||
|
readTime: true
|
||||||
|
autonumber: true
|
||||||
|
math: true
|
||||||
|
tags: ["database", "java"]
|
||||||
|
showTags: false
|
||||||
|
hideBackToTop: false
|
||||||
|
fediverse: "@username@instance.url"
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you use the theme or found it useful you can support me by leaving a star :star: to Typo's Github repository or opening issues and PRs with fixes or new features.
|