Static updates (#1)
ci/woodpecker/push/goreleaser Pipeline was successful Details
ci/woodpecker/tag/goreleaser Pipeline was successful Details

Co-authored-by: jolheiser <john.olheiser@gmail.com>
Reviewed-on: #1
pull/2/head v0.0.1
jolheiser 2022-07-07 17:27:57 +00:00
parent 447c88febe
commit 5920853468
No known key found for this signature in database
GPG Key ID: 454E7F878890995A
15 changed files with 408 additions and 246 deletions

View File

@ -1,17 +0,0 @@
---
kind: pipeline
name: compliance
trigger:
event:
- pull_request
steps:
- name: test
pull: always
image: golang:1.17
commands:
- go test -race ./...
- name: vet
pull: always
image: golang:1.17
commands:
- go vet -race ./...

23
.goreleaser.yaml 100644
View File

@ -0,0 +1,23 @@
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
archives:
- replacements:
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
release:
gitea:
owner: jolheiser
name: blog
gitea_urls:
api: https://git.jojodev.com/api/v1/
download: https://git.jojodev.com

View File

@ -0,0 +1,39 @@
clone:
git:
image: woodpeckerci/plugin-git
settings:
tags: true
pipeline:
compliance:
image: golang:1.18
commands:
- go test -race ./...
- go vet ./...
- go run github.com/rs/zerolog/cmd/lint@latest go.jolheiser.com/blog
when:
event: pull_request
build:
image: goreleaser/goreleaser
commands:
- goreleaser build --snapshot
when:
event: pull_request
release:
image: goreleaser/goreleaser
commands:
- goreleaser release
secrets: [ gitea_token ]
when:
event: tag
prune:
image: jolheiser/drone-gitea-prune
settings:
base: https://git.jojodev.com
token:
from_secret: gitea_token
when:
event: tag

View File

@ -6,4 +6,4 @@ SELECT
FROM
users
WHERE
email = 'john.olheiser@gmail.com';
email = 'john@jolheiser.com';

View File

@ -3,3 +3,77 @@ title = "Testing"
date = 2021-08-19
tags = ["foo", "bar"]
---
# Lorem
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
```text {name="test"}
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
```
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Imperdiet proin fermentum leo vel. Consectetur adipiscing elit ut aliquam purus sit amet. Aliquam etiam erat velit scelerisque in. Amet facilisis magna etiam tempor orci eu lobortis elementum nibh. Nullam non nisi est sit amet facilisis magna etiam tempor. Orci nulla pellentesque dignissim enim sit amet. Diam quis enim lobortis scelerisque fermentum. Nulla malesuada pellentesque elit eget gravida. Vitae et leo duis ut diam quam. Metus vulputate eu scelerisque felis. Orci eu lobortis elementum nibh tellus molestie nunc non. Eu volutpat odio facilisis mauris. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Porttitor eget dolor morbi non arcu risus quis varius quam. Nulla facilisi nullam vehicula ipsum a. Turpis egestas maecenas pharetra convallis posuere morbi leo. Venenatis a condimentum vitae sapien pellentesque habitant morbi tristique senectus. Et netus et malesuada fames ac.
Varius vel pharetra vel turpis nunc eget. Faucibus vitae aliquet nec ullamcorper sit. Id semper risus in hendrerit gravida rutrum quisque non. Metus dictum at tempor commodo ullamcorper a lacus vestibulum. Cursus euismod quis viverra nibh cras pulvinar mattis nunc sed. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Ut morbi tincidunt augue interdum velit. Habitant morbi tristique senectus et netus et malesuada. Nunc faucibus a pellentesque sit. Lectus arcu bibendum at varius vel pharetra vel turpis. Fermentum dui faucibus in ornare quam viverra.
At risus viverra adipiscing at. Blandit massa enim nec dui. Habitant morbi tristique senectus et netus et malesuada. Posuere morbi leo urna molestie at elementum eu. Lectus arcu bibendum at varius vel pharetra vel. Lacinia quis vel eros donec ac odio tempor. Iaculis nunc sed augue lacus viverra vitae. Vitae proin sagittis nisl rhoncus. Fermentum odio eu feugiat pretium nibh ipsum consequat nisl. Eu tincidunt tortor aliquam nulla facilisi cras. Turpis tincidunt id aliquet risus feugiat in ante. Quis imperdiet massa tincidunt nunc. Sit amet cursus sit amet dictum. Ornare arcu dui vivamus arcu felis bibendum.
Diam vulputate ut pharetra sit amet aliquam. Facilisis mauris sit amet massa vitae tortor condimentum lacinia quis. Vulputate dignissim suspendisse in est ante in nibh. Mauris vitae ultricies leo integer malesuada nunc. Sollicitudin tempor id eu nisl nunc mi ipsum faucibus vitae. In cursus turpis massa tincidunt dui ut. Tellus in hac habitasse platea dictumst. Amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar. Arcu non sodales neque sodales ut etiam sit. Amet commodo nulla facilisi nullam vehicula ipsum a. Ante in nibh mauris cursus mattis molestie a iaculis at. Aliquet risus feugiat in ante metus dictum at. Vel quam elementum pulvinar etiam non. Et magnis dis parturient montes nascetur. Mauris nunc congue nisi vitae suscipit tellus mauris. Eget egestas purus viverra accumsan in nisl nisi. Tincidunt arcu non sodales neque.
Vulputate odio ut enim blandit volutpat maecenas volutpat blandit. Laoreet suspendisse interdum consectetur libero id faucibus nisl tincidunt. Pellentesque id nibh tortor id aliquet lectus proin nibh. Suscipit adipiscing bibendum est ultricies integer quis. Consequat mauris nunc congue nisi vitae. Tellus cras adipiscing enim eu turpis egestas pretium aenean. Tortor vitae purus faucibus ornare suspendisse sed nisi lacus. Porttitor eget dolor morbi non arcu risus quis. Maecenas accumsan lacus vel facilisis volutpat est velit egestas. Faucibus ornare suspendisse sed nisi lacus sed viverra tellus in. Cras sed felis eget velit aliquet sagittis id consectetur. Rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque. Habitant morbi tristique senectus et. Velit dignissim sodales ut eu. Viverra vitae congue eu consequat ac felis donec et odio. Gravida arcu ac tortor dignissim convallis aenean et tortor at. Mauris pellentesque pulvinar pellentesque habitant morbi tristique.
Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Gravida cum sociis natoque penatibus et magnis. Fames ac turpis egestas integer eget aliquet. Scelerisque eu ultrices vitae auctor eu augue ut. Tempor orci dapibus ultrices in iaculis nunc sed augue lacus. Orci eu lobortis elementum nibh tellus molestie. Non pulvinar neque laoreet suspendisse interdum. Purus faucibus ornare suspendisse sed. Sed adipiscing diam donec adipiscing tristique risus. Tristique sollicitudin nibh sit amet commodo nulla. Dictum fusce ut placerat orci nulla pellentesque dignissim. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet.
Pretium viverra suspendisse potenti nullam ac tortor vitae purus. Nam aliquam sem et tortor. Ut porttitor leo a diam sollicitudin tempor id eu nisl. Consequat id porta nibh venenatis cras. Proin sagittis nisl rhoncus mattis. Dictum fusce ut placerat orci nulla pellentesque dignissim enim sit. Blandit aliquam etiam erat velit. Nec ullamcorper sit amet risus nullam eget. Suscipit tellus mauris a diam maecenas sed. Justo eget magna fermentum iaculis eu non diam. Vivamus arcu felis bibendum ut. Fermentum dui faucibus in ornare quam viverra orci sagittis. Varius morbi enim nunc faucibus a pellentesque sit amet. Dignissim diam quis enim lobortis scelerisque fermentum dui faucibus in. Sed elementum tempus egestas sed sed risus pretium quam. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Rhoncus urna neque viverra justo nec.
Parturient montes nascetur ridiculus mus mauris vitae. Dolor sed viverra ipsum nunc aliquet bibendum enim facilisis. Vestibulum mattis ullamcorper velit sed. Magna fringilla urna porttitor rhoncus dolor purus. Morbi tincidunt ornare massa eget egestas purus viverra accumsan. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. Lacus viverra vitae congue eu consequat ac felis. Dolor sit amet consectetur adipiscing. Semper feugiat nibh sed pulvinar proin gravida. Iaculis eu non diam phasellus vestibulum. Viverra aliquet eget sit amet tellus cras. A iaculis at erat pellentesque adipiscing commodo elit. Potenti nullam ac tortor vitae. Augue interdum velit euismod in pellentesque massa placerat. Id ornare arcu odio ut sem nulla pharetra. Aliquet risus feugiat in ante metus dictum at tempor.
Hac habitasse platea dictumst vestibulum rhoncus est pellentesque elit. Eu sem integer vitae justo eget magna fermentum. In egestas erat imperdiet sed euismod nisi porta lorem. Amet aliquam id diam maecenas ultricies. Ornare massa eget egestas purus viverra. Pharetra convallis posuere morbi leo urna. Dignissim suspendisse in est ante in nibh mauris cursus. Erat velit scelerisque in dictum. Feugiat nisl pretium fusce id velit ut tortor pretium viverra. Placerat vestibulum lectus mauris ultrices eros. Nisl pretium fusce id velit ut tortor. Cum sociis natoque penatibus et. Aliquet porttitor lacus luctus accumsan tortor posuere. Et pharetra pharetra massa massa ultricies mi quis hendrerit dolor. Pellentesque massa placerat duis ultricies lacus sed. Nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Ac ut consequat semper viverra nam libero justo. Pretium aenean pharetra magna ac placerat vestibulum lectus.
```text
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
```
Est lorem ipsum dolor sit. Donec ac odio tempor orci dapibus. Dui sapien eget mi proin sed. Dolor sit amet consectetur adipiscing elit ut. Eu nisl nunc mi ipsum faucibus. Nam libero justo laoreet sit amet cursus sit. Odio aenean sed adipiscing diam donec adipiscing tristique risus. Volutpat blandit aliquam etiam erat velit scelerisque in dictum. Erat nam at lectus urna duis. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Nulla facilisi etiam dignissim diam quis enim lobortis scelerisque fermentum. Posuere ac ut consequat semper viverra. Volutpat blandit aliquam etiam erat velit scelerisque. Pretium vulputate sapien nec sagittis aliquam. Pellentesque id nibh tortor id. Non arcu risus quis varius. Pharetra magna ac placerat vestibulum lectus mauris. Mi proin sed libero enim sed faucibus. Maecenas ultricies mi eget mauris pharetra.
Nullam non nisi est sit amet facilisis magna. A erat nam at lectus urna duis convallis. Lacinia at quis risus sed vulputate odio ut. Tristique risus nec feugiat in. Morbi enim nunc faucibus a pellentesque sit amet porttitor eget. Orci ac auctor augue mauris augue neque gravida. Aliquet lectus proin nibh nisl condimentum id venenatis a. Imperdiet sed euismod nisi porta lorem mollis aliquam ut porttitor. Massa tincidunt dui ut ornare lectus. Id donec ultrices tincidunt arcu. Vitae ultricies leo integer malesuada nunc. Gravida in fermentum et sollicitudin ac. Et malesuada fames ac turpis egestas sed tempus urna. Cursus risus at ultrices mi tempus imperdiet nulla malesuada. Elementum pulvinar etiam non quam lacus suspendisse faucibus interdum posuere. Tellus integer feugiat scelerisque varius morbi enim nunc. Sed risus ultricies tristique nulla aliquet enim tortor. Enim nulla aliquet porttitor lacus luctus. Fermentum dui faucibus in ornare quam viverra.
Placerat orci nulla pellentesque dignissim enim sit amet. Tempus egestas sed sed risus. Elit sed vulputate mi sit amet mauris. Amet consectetur adipiscing elit duis tristique sollicitudin. Venenatis tellus in metus vulputate eu. Mattis pellentesque id nibh tortor id aliquet. Facilisis leo vel fringilla est ullamcorper eget nulla facilisi etiam. Est ullamcorper eget nulla facilisi etiam dignissim diam. Lorem ipsum dolor sit amet consectetur adipiscing elit duis. Amet nulla facilisi morbi tempus iaculis. Et netus et malesuada fames ac. Dolor sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Nulla pharetra diam sit amet nisl suscipit adipiscing bibendum. Purus in massa tempor nec feugiat nisl pretium fusce. Adipiscing commodo elit at imperdiet. Magna etiam tempor orci eu lobortis elementum nibh tellus molestie. Nec tincidunt praesent semper feugiat. Tempus egestas sed sed risus. Facilisis magna etiam tempor orci eu.
Ultrices gravida dictum fusce ut placerat orci nulla. Viverra nibh cras pulvinar mattis nunc. Nisl vel pretium lectus quam id leo in vitae turpis. Sed lectus vestibulum mattis ullamcorper velit sed. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare. Aliquam etiam erat velit scelerisque. Amet consectetur adipiscing elit ut aliquam. Amet consectetur adipiscing elit duis tristique sollicitudin nibh. Cursus in hac habitasse platea dictumst quisque sagittis. Sem et tortor consequat id.
Nisi quis eleifend quam adipiscing vitae proin. Nibh sit amet commodo nulla facilisi nullam vehicula ipsum a. Eget egestas purus viverra accumsan in nisl nisi scelerisque eu. Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut. Ut faucibus pulvinar elementum integer enim neque volutpat ac. Egestas pretium aenean pharetra magna ac. Volutpat diam ut venenatis tellus in metus vulputate eu scelerisque. Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Velit scelerisque in dictum non consectetur a erat. Massa placerat duis ultricies lacus sed turpis tincidunt id. Auctor augue mauris augue neque gravida. Id velit ut tortor pretium viverra suspendisse potenti nullam.
```text
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
```
At auctor urna nunc id cursus metus aliquam eleifend mi. Donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum arcu. Tellus orci ac auctor augue mauris augue neque gravida. Vitae congue eu consequat ac felis donec et odio. Laoreet sit amet cursus sit amet dictum sit amet. Gravida quis blandit turpis cursus in hac. Habitant morbi tristique senectus et netus et. Sed libero enim sed faucibus turpis in eu. Nisl vel pretium lectus quam id leo. Non pulvinar neque laoreet suspendisse interdum consectetur libero id.
Nibh ipsum consequat nisl vel pretium lectus. Nulla aliquet enim tortor at auctor urna nunc id cursus. Arcu dictum varius duis at consectetur lorem donec massa sapien. Faucibus in ornare quam viverra orci sagittis eu volutpat. Vel facilisis volutpat est velit egestas. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae purus. Dolor purus non enim praesent elementum facilisis leo. Tortor pretium viverra suspendisse potenti nullam ac tortor. Risus viverra adipiscing at in tellus integer feugiat scelerisque varius. Aliquet eget sit amet tellus cras adipiscing enim. Habitant morbi tristique senectus et netus et. At varius vel pharetra vel turpis nunc. Nulla facilisi etiam dignissim diam quis. Morbi enim nunc faucibus a pellentesque sit amet porttitor eget. Diam maecenas sed enim ut sem viverra.
Sit amet commodo nulla facilisi nullam vehicula ipsum a. Augue eget arcu dictum varius duis at. Netus et malesuada fames ac. Quis hendrerit dolor magna eget. Id faucibus nisl tincidunt eget nullam non nisi. Sit amet justo donec enim diam vulputate ut pharetra sit. Praesent tristique magna sit amet purus gravida quis blandit. Porttitor leo a diam sollicitudin tempor id eu. Magna fringilla urna porttitor rhoncus dolor purus non. Quam id leo in vitae turpis.
Arcu odio ut sem nulla pharetra diam sit amet. Fringilla phasellus faucibus scelerisque eleifend. Diam in arcu cursus euismod quis viverra nibh cras pulvinar. Lorem ipsum dolor sit amet consectetur adipiscing elit. Et egestas quis ipsum suspendisse ultrices gravida dictum fusce ut. Lectus nulla at volutpat diam ut venenatis. Est lorem ipsum dolor sit amet consectetur adipiscing elit pellentesque. Vel turpis nunc eget lorem dolor sed viverra ipsum nunc. Netus et malesuada fames ac turpis egestas maecenas pharetra convallis. Placerat orci nulla pellentesque dignissim enim sit amet venenatis. Ultrices eros in cursus turpis. Molestie at elementum eu facilisis sed odio. Euismod nisi porta lorem mollis aliquam ut porttitor leo. Aliquet risus feugiat in ante metus dictum at. Vitae auctor eu augue ut. Amet mauris commodo quis imperdiet massa tincidunt nunc. Vel pretium lectus quam id leo in vitae turpis massa. At consectetur lorem donec massa sapien faucibus. Elit ullamcorper dignissim cras tincidunt lobortis.
A arcu cursus vitae congue mauris rhoncus aenean. Convallis posuere morbi leo urna molestie at elementum eu facilisis. Condimentum vitae sapien pellentesque habitant morbi. Sociis natoque penatibus et magnis. Morbi tristique senectus et netus et malesuada fames. Ullamcorper malesuada proin libero nunc consequat. Egestas erat imperdiet sed euismod nisi porta lorem mollis. Volutpat diam ut venenatis tellus. Venenatis tellus in metus vulputate eu. Ultricies tristique nulla aliquet enim tortor at auctor urna. Sed risus ultricies tristique nulla aliquet enim tortor at. Posuere urna nec tincidunt praesent semper feugiat nibh. Donec et odio pellentesque diam volutpat. Bibendum est ultricies integer quis auctor elit sed vulputate mi. Nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Ullamcorper malesuada proin libero nunc consequat interdum varius.
Sollicitudin nibh sit amet commodo nulla facilisi nullam. Enim eu turpis egestas pretium. Sem et tortor consequat id porta nibh. Sagittis aliquam malesuada bibendum arcu vitae. Eu ultrices vitae auctor eu augue ut lectus. Dictum varius duis at consectetur lorem donec massa. Dictum varius duis at consectetur lorem donec massa sapien faucibus. Montes nascetur ridiculus mus mauris vitae ultricies leo integer malesuada. Enim nec dui nunc mattis enim ut tellus. Justo donec enim diam vulputate ut. Commodo nulla facilisi nullam vehicula ipsum a. Mauris augue neque gravida in fermentum et. Mauris ultrices eros in cursus turpis massa tincidunt dui. Egestas sed sed risus pretium quam vulputate dignissim suspendisse in. Odio facilisis mauris sit amet massa vitae tortor condimentum.

View File

@ -1,75 +0,0 @@
package main
import (
"fmt"
"github.com/goyek/goyek"
)
const zerologLintVer = "1.24.0"
func main() {
flow().Main()
}
func flow() *goyek.Flow {
flow := &goyek.Flow{}
fmt := flow.Register(taskFmt)
test := flow.Register(taskTest)
vet := flow.Register(taskVet)
lint := flow.Register(taskLint)
flow.DefaultTask = flow.Register(goyek.Task{
Name: "all",
Usage: "Run all flows",
Deps: []goyek.RegisteredTask{
fmt,
lint,
test,
vet,
},
})
return flow
}
var taskFmt = goyek.Task{
Name: "fmt",
Usage: "go fmt",
Action: func(tf *goyek.TF) {
if err := tf.Cmd("go", "fmt", "./...").Run(); err != nil {
tf.Fatal(err)
}
},
}
var taskTest = goyek.Task{
Name: "test",
Usage: "go test",
Action: func(tf *goyek.TF) {
if err := tf.Cmd("go", "test", "-race", "./...").Run(); err != nil {
tf.Fatal(err)
}
},
}
var taskVet = goyek.Task{
Name: "vet",
Usage: "go vet",
Action: func(tf *goyek.TF) {
if err := tf.Cmd("go", "vet", "-race", "./...").Run(); err != nil {
tf.Fatal(err)
}
},
}
var taskLint = goyek.Task{
Name: "lint",
Usage: "Run linter(s)",
Action: func(tf *goyek.TF) {
if err := tf.Cmd("go", "run", fmt.Sprintf("github.com/rs/zerolog/cmd/lint@v%s", zerologLintVer), ".").Run(); err != nil {
tf.Fatal(err)
}
},
}

9
go.mod
View File

@ -3,19 +3,20 @@ module go.jolheiser.com/blog
go 1.17
require (
github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a
github.com/alecthomas/chroma v0.10.0
github.com/fsnotify/fsnotify v1.5.4
github.com/go-chi/chi/v5 v5.0.4
github.com/goyek/goyek v0.6.0
github.com/pelletier/go-toml/v2 v2.0.0-beta.3
github.com/peterbourgon/ff/v3 v3.1.0
github.com/rs/zerolog v1.24.0
github.com/yuin/goldmark v1.4.0
github.com/yuin/goldmark-emoji v1.0.1
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01
go.jolheiser.com/chroma-catppuccin v0.0.2
go.jolheiser.com/emdbed v0.0.2
)
require (
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
github.com/dlclark/regexp2 v1.2.0 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
)

24
go.sum
View File

@ -1,31 +1,30 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a h1:3v1NrYWWqp2S72e4HLgxKt83B3l0lnORDholH/ihoMM=
github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/goyek/goyek v0.6.0 h1:2YQ4V3X7q+zFF98IBWMc1WRwfzs0TQ8jrwOKY3XRQRk=
github.com/goyek/goyek v0.6.0/go.mod h1:UGjZz3juJL2l2eMqRbxQYjG8ieyKb7WMYPv0KB0KVxA=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
@ -41,11 +40,11 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.24.0 h1:76ivFxmVSRs1u2wUwJVg5VZDYQgeH1JpoS6ndgr9Wy8=
github.com/rs/zerolog v1.24.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU=
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -57,6 +56,8 @@ github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18W
github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01 h1:0SJnXjE4jDClMW6grE0xpNhwpqbPwkBTn8zpVw5C0SI=
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01/go.mod h1:TwKQPa5XkCCRC2GRZ5wtfNUTQ2+9/i19mGRijFeJ4BE=
go.jolheiser.com/chroma-catppuccin v0.0.2 h1:s5iK/XgmeagVGnq/3ybaxccDxZf4ohrkzAUFANQK3wA=
go.jolheiser.com/chroma-catppuccin v0.0.2/go.mod h1:eHY2bDa7Zryc+2Q9f51YUNUSZGQUl3tOU8lJdsZCViA=
go.jolheiser.com/emdbed v0.0.2 h1:nFxYD7VOlsp9Mv0nKnWe8Zj9n43yLJU5Yge/Va7my1E=
go.jolheiser.com/emdbed v0.0.2/go.mod h1:8ReMCKEDv6UT89SqYZ+wzbPTGs3xNuX8q2RAsmSSG1M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -72,8 +73,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

18
main.go
View File

@ -20,10 +20,11 @@ func main() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
middleware.DefaultLogger = middleware.RequestLogger(&middleware.DefaultLogFormatter{Logger: &log.Logger, NoColor: true})
fs := flag.NewFlagSet("blog", flag.ExitOnError)
postPath := fs.String("post-dir", "posts", "Path to posts directory")
port := fs.Int("port", 8080, "Port to serve on")
fs := flag.NewFlagSet("blog", flag.ContinueOnError)
postDirFlag := fs.String("post-dir", "posts", "Path to posts directory")
portFlag := fs.Int("port", 8080, "Port to serve on")
fs.String("config", "", "Config file")
debugFlag := fs.Bool("debug", false, "Debug mode")
if err := ff.Parse(fs, os.Args[1:],
ff.WithEnvVarPrefix("BLOG"),
ff.WithConfigFileFlag("config"),
@ -33,7 +34,13 @@ func main() {
return
}
b, err := post.NewBlog(*postPath)
if *debugFlag {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
b, err := post.NewBlog(*postDirFlag)
if err != nil {
log.Error().Err(err).Msg("could not init blog")
return
@ -41,7 +48,8 @@ func main() {
r := router.New(b)
go func() {
if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), r); err != nil {
log.Info().Msgf("listening at http://localhost:%d", *portFlag)
if err := http.ListenAndServe(fmt.Sprintf(":%d", *portFlag), r); err != nil {
log.Error().Err(err).Msg("could not open server")
}
}()

View File

@ -2,6 +2,7 @@ package markdown
import (
"bytes"
"fmt"
"io"
chromahtml "github.com/alecthomas/chroma/formatters/html"
@ -11,28 +12,37 @@ import (
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
_ "go.jolheiser.com/chroma-catppuccin/chroma1"
)
var gm = goldmark.New(
goldmark.WithExtensions(
extension.GFM,
highlighting.NewHighlighting(
highlighting.WithStyle("monokai"),
highlighting.WithFormatOptions(
chromahtml.WithLineNumbers(true),
chromahtml.LinkableLineNumbers(true, "code-"),
chromahtml.LineNumbersInTable(true),
var gm = func() goldmark.Markdown {
var codeblockIdx int
return goldmark.New(
goldmark.WithExtensions(
extension.GFM,
highlighting.NewHighlighting(
highlighting.WithStyle("catppuccin"),
highlighting.WithFormatOptions(
chromahtml.WithLineNumbers(true),
chromahtml.LineNumbersInTable(true),
),
highlighting.WithCodeBlockOptions(func(ctx highlighting.CodeBlockContext) []chromahtml.Option {
codeblockIdx++
return []chromahtml.Option{
chromahtml.LinkableLineNumbers(true, fmt.Sprintf("code%d-", codeblockIdx)),
}
}),
),
emoji.Emoji,
),
emoji.Emoji,
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
),
)
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
),
)
}
// Convert transforms a markdown document into HTML
func Convert(r io.Reader) (string, error) {
@ -41,7 +51,7 @@ func Convert(r io.Reader) (string, error) {
return "", err
}
var buf bytes.Buffer
if err := gm.Convert(content, &buf); err != nil {
if err := gm().Convert(content, &buf); err != nil {
return "", err
}
return buf.String(), nil

View File

@ -1,29 +1,65 @@
package post
import (
"html/template"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
"go.jolheiser.com/blog/markdown"
"github.com/fsnotify/fsnotify"
"github.com/rs/zerolog/log"
"go.jolheiser.com/emdbed"
)
func NewBlog(basePath string) (*Blog, error) {
posts, err := Scan(basePath)
posts, err := scan(basePath)
if err != nil {
return nil, err
}
return &Blog{
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
if err := watcher.Add(basePath); err != nil {
return nil, err
}
b := &Blog{
Path: basePath,
Posts: posts,
}, nil
posts: posts,
}
go func() {
var debounce time.Time
for {
select {
case event := <-watcher.Events:
log.Debug().Str("op", event.Op.String()).Msgf("fsnotify %q", event.Name)
debounce = time.Now()
case err := <-watcher.Errors:
log.Err(err).Msg("")
default:
if !debounce.IsZero() && time.Since(debounce) > (time.Second*5) {
log.Info().Msg("reloading blog")
if err := b.Scan(); err != nil {
log.Err(err).Msg("")
}
debounce = time.Time{}
}
}
}
}()
return b, nil
}
func Scan(basePath string) (map[string]*Post, error) {
func scan(basePath string) (map[string]*Post, error) {
posts := make(map[string]*Post)
ents, err := os.ReadDir(basePath)
if err != nil {
@ -55,22 +91,40 @@ func Scan(basePath string) (map[string]*Post, error) {
continue
}
posts[post.Slug] = post
if err := fi.Close(); err != nil {
log.Error().Err(err).Msg("could not close file")
continue
}
if err := post.Load(); err != nil {
log.Err(err).Msg("could not load post")
continue
}
}
return posts, nil
}
type Blog struct {
Path string
Posts map[string]*Post
posts map[string]*Post
mx sync.RWMutex
}
func (b *Blog) Scan() error {
posts, err := scan(b.Path)
if err != nil {
return err
}
b.mx.Lock()
defer b.mx.Unlock()
b.posts = posts
return nil
}
func (b *Blog) SortedPosts() []*Post {
posts := make([]*Post, 0, len(b.Posts))
for _, post := range b.Posts {
posts := make([]*Post, 0, len(b.posts))
for _, post := range b.posts {
posts = append(posts, post)
}
sort.Slice(posts, func(i, j int) bool {
@ -79,11 +133,47 @@ func (b *Blog) SortedPosts() []*Post {
return posts
}
type Post struct {
Path string `toml:"-"`
Slug string `toml:"-"`
Title string `toml:"title"`
Author string `toml:"author"`
Date time.Time `toml:"date"`
Tags []string `toml:"tags"`
func (b *Blog) Post(name string) (*Post, bool) {
b.mx.RLock()
defer b.mx.RUnlock()
if post, ok := b.posts[name]; ok {
return post, true
}
return nil, false
}
type Post struct {
Path string `toml:"-"`
Slug string `toml:"-"`
Content template.HTML `toml:"-"`
Title string `toml:"title"`
Author string `toml:"author"`
Date time.Time `toml:"date"`
Tags []string `toml:"tags"`
}
func (p *Post) Load() error {
fi, err := os.Open(p.Path)
if err != nil {
return err
}
defer fi.Close()
mdContent, err := markdown.Content(fi)
if err != nil {
return err
}
emdbedContent, err := emdbed.Convert(filepath.Dir(p.Path), strings.NewReader(mdContent))
if err != nil {
return err
}
md, err := markdown.Convert(strings.NewReader(emdbedContent))
if err != nil {
return err
}
p.Content = template.HTML(md)
return nil
}

View File

@ -1,15 +1,8 @@
package router
import (
"html/template"
"net/http"
"os"
"path/filepath"
"strings"
"go.jolheiser.com/emdbed"
"go.jolheiser.com/blog/markdown"
"go.jolheiser.com/blog/post"
"go.jolheiser.com/blog/static"
@ -26,16 +19,16 @@ func New(blog *post.Blog) *chi.Mux {
m.Get("/", indexHandler(blog))
m.Get("/{post}", fileHandler(blog))
m.Get("/sakura.css", static.SakuraCSS)
m.Route("/_", func(r chi.Router) {
r.Get("/sakura.css", static.SakuraCSS)
})
return m
}
func indexHandler(blog *post.Blog) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := static.IndexTemplate.Execute(w, map[string]interface{}{
"Blog": blog,
}); err != nil {
if err := static.IndexTemplate.Execute(w, blog); err != nil {
log.Error().Err(err).Msg("could not execute template")
}
}
@ -44,44 +37,13 @@ func indexHandler(blog *post.Blog) http.HandlerFunc {
func fileHandler(blog *post.Blog) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
postName := chi.URLParam(r, "post")
p, ok := blog.Posts[postName]
p, ok := blog.Post(postName)
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
fi, err := os.Open(p.Path)
if err != nil {
log.Error().Err(err).Msg("could not open post")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer fi.Close()
mdContent, err := markdown.Content(fi)
if err != nil {
log.Error().Err(err).Msg("could not get content")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
emdbedContent, err := emdbed.Convert(filepath.Dir(p.Path), strings.NewReader(mdContent))
if err != nil {
log.Error().Err(err).Msg("could not emdbed")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
md, err := markdown.Convert(strings.NewReader(emdbedContent))
if err != nil {
log.Error().Err(err).Msg("could not convert")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := static.PostTemplate.Execute(w, map[string]interface{}{
"Post": p,
"Content": template.HTML(md),
}); err != nil {
if err := static.PostTemplate.Execute(w, p); err != nil {
log.Error().Err(err).Msg("could not execute template")
}
}

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<title>Blog</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="sakura.css"/>
<link rel="stylesheet" href="_/sakura.css"/>
<style>
.tag {
font-size: .7em;
@ -20,7 +20,7 @@
</head>
<body>
<h1 class="title">Blog Posts</h1>
{{range .Blog.SortedPosts}}
{{range .SortedPosts}}
<h5>
<a href="{{.Slug}}"><strong>{{.Title}}</strong></a><br/>
{{if .Author}}<small>@{{.Author}}</small>{{end}}<span class="right">{{.Date.Format "Jan 2, 2006"}}</span><br/>

View File

@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{.Post.Title}}</title>
<title>{{.Title}}</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="sakura.css"/>
<link rel="stylesheet" href="_/sakura.css"/>
</head>
<body>
<a style="position: absolute; left: 1em;" href="../">Index</a>
<a style="position: absolute; left: 1em;" href="../../">Index</a>
{{.Content}}
</body>
<script>

View File

@ -6,44 +6,50 @@
/* Default Sakura Theme */
:root {
--color-blossom: #1d7484;
--color-fade: #982c61;
--color-bg: #f9f9f9;
--color-bg-alt: #f1f1f1;
--color-text: #4a4a4a;
--color-blossom: #dc8a78;
--color-fade: #acb0be;
--color-bg: #eff1f5;
--color-bg-alt: #dce0e8;
--color-text: #4c4f69;
}
/* Sakura Dark Theme */
@media (prefers-color-scheme: dark) {
:root {
--color-blossom: #ffffff;
--color-fade: #c9c9c9;
--color-bg: #222222;
--color-bg-alt: #4a4a4a;
--color-text: #c9c9c9;
--color-blossom: #f5e0dc;
--color-fade: #585b70;
--color-bg: #1e1e2e;
--color-bg-alt: #11111b;
--color-text: #cdd6f4;
}
}
html {
font-size: 62.5%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; }
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
}
body {
font-size: 1.8rem;
line-height: 1.618;
max-width: 50%;
max-width: 38em;
margin: auto;
color: var(--color-text);
background-color: var(--color-bg);
padding: 13px; }
padding: 13px;
}
@media (max-width: 684px) {
body {
font-size: 1.53rem; } }
font-size: 1.53rem;
}
}
@media (max-width: 382px) {
body {
font-size: 1.35rem; } }
font-size: 1.35rem;
}
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.1;
@ -54,52 +60,69 @@ h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word; }
word-break: break-word;
}
h1 {
font-size: 2.35em; }
font-size: 2.35em;
}
h2 {
font-size: 2.00em; }
font-size: 2.00em;
}
h3 {
font-size: 1.75em; }
font-size: 1.75em;
}
h4 {
font-size: 1.5em; }
font-size: 1.5em;
}
h5 {
font-size: 1.25em; }
font-size: 1.25em;
}
h6 {
font-size: 1em; }
font-size: 1em;
}
p {
margin-top: 0px;
margin-bottom: 2.5rem; }
margin-bottom: 2.5rem;
}
small, sub, sup {
font-size: 75%; }
font-size: 75%;
}
hr {
border-color: var(--color-blossom); }
border-color: var(--color-blossom);
}
a {
text-decoration: none;
color: var(--color-blossom); }
color: var(--color-blossom);
}
a:hover {
color: var(--color-fade);
border-bottom: 2px solid var(--color-text); }
border-bottom: 2px solid var(--color-text);
}
a:visited {
color: var(--color-blossom); }
color: var(--color-blossom);
}
ul {
padding-left: 1.4em;
margin-top: 0px;
margin-bottom: 2.5rem; }
margin-bottom: 2.5rem;
}
li {
margin-bottom: 0.4em; }
margin-bottom: 0.4em;
}
blockquote {
margin-left: 0px;
@ -110,55 +133,67 @@ blockquote {
padding-right: 0.8em;
border-left: 5px solid var(--color-blossom);
margin-bottom: 2.5rem;
background-color: var(--color-bg-alt); }
background-color: var(--color-bg-alt);
}
blockquote p {
margin-bottom: 0; }
margin-bottom: 0;
}
img, video {
height: auto;
max-width: 100%;
margin-top: 0px;
margin-bottom: 2.5rem; }
margin-bottom: 2.5rem;
}
/* Pre and Code */
pre {
font-size: 0.9em;
background-color: var(--color-bg-alt);
display: block;
padding: 1em;
overflow-x: auto;
margin-top: 0px;
margin-bottom: 2.5rem; }
margin-bottom: 2.5rem;
}
code {
font-size: 0.9em;
padding: 0 0.5em;
background-color: var(--color-bg-alt);
white-space: pre-wrap; }
white-space: pre-wrap;
}
pre > code {
padding: 0;
background-color: transparent;
white-space: pre; }
white-space: pre;
}
/* Tables */
table {
text-align: justify;
width: 100%;
border-collapse: collapse; }
border-collapse: collapse;
}
td, th {
padding: 0.5em;
border-bottom: 1px solid var(--color-bg-alt); }
border-bottom: 1px solid var(--color-bg-alt);
}
/* Buttons, forms and input */
input, textarea {
border: 1px solid var(--color-text); }
border: 1px solid var(--color-text);
}
input:focus, textarea:focus {
border: 1px solid var(--color-blossom); }
border: 1px solid var(--color-blossom);
}
textarea {
width: 100%; }
width: 100%;
}
.button, button, input[type="submit"], input[type="reset"], input[type="button"] {
display: inline-block;
@ -171,15 +206,20 @@ textarea {
border-radius: 1px;
border: 1px solid var(--color-blossom);
cursor: pointer;
box-sizing: border-box; }
box-sizing: border-box;
}
.button[disabled], button[disabled], input[type="submit"][disabled], input[type="reset"][disabled], input[type="button"][disabled] {
cursor: default;
opacity: .5; }
opacity: .5;
}
.button:focus:enabled, .button:hover:enabled, button:focus:enabled, button:hover:enabled, input[type="submit"]:focus:enabled, input[type="submit"]:hover:enabled, input[type="reset"]:focus:enabled, input[type="reset"]:hover:enabled, input[type="button"]:focus:enabled, input[type="button"]:hover:enabled {
background-color: var(--color-fade);
border-color: var(--color-fade);
color: var(--color-bg);
outline: 0; }
outline: 0;
}
textarea, select, input {
color: var(--color-text);
@ -187,18 +227,23 @@ textarea, select, input {
/* The 6px vertically centers text on FF, ignored by Webkit */
margin-bottom: 10px;
background-color: var(--color-bg-alt);
border: 1px solid var(--color-bg-alt );
border: 1px solid var(--color-bg-alt);
border-radius: 4px;
box-shadow: none;
box-sizing: border-box; }
box-sizing: border-box;
}
textarea:focus, select:focus, input:focus {
border: 1px solid var(--color-blossom);
outline: 0; }
outline: 0;
}
input[type="checkbox"]:focus {
outline: 1px dotted var(--color-blossom); }
outline: 1px dotted var(--color-blossom);
}
label, legend, fieldset {
display: block;
margin-bottom: .5rem;
font-weight: 600; }
font-weight: 600;
}