mirror of
https://git.sr.ht/~seirdy/seirdy.one
synced 2024-11-27 14:12:09 +00:00
Compare commits
5 commits
48a9088ca1
...
6042b0bdaf
Author | SHA1 | Date | |
---|---|---|---|
|
6042b0bdaf | ||
|
b9ee2b3e20 | ||
|
5f48ca7bbe | ||
|
b42212f158 | ||
|
bd705cd0b1 |
13 changed files with 178 additions and 41 deletions
116
README.md
116
README.md
|
@ -15,56 +15,118 @@ Dependencies
|
||||||
To build:
|
To build:
|
||||||
|
|
||||||
- Hugo 0.93 or later
|
- Hugo 0.93 or later
|
||||||
- Make
|
- bmake or GNU Make. OpenBSD make (omake) should work too, but I haven't tested it.
|
||||||
- Git (Hugo uses Git info for features like date last updated)
|
- Git (Hugo uses Git info for features like date last updated)
|
||||||
|
- [htmlq](https://github.com/mgdm/htmlq), to parse HTML when fetching some webring links and for some post-processing.
|
||||||
|
- POSIX utils: `grep`, `find`, POSIX-compliant `/bin/sh`, etc.
|
||||||
|
|
||||||
|
Before deploying, I use some tools to process the output.
|
||||||
|
|
||||||
|
- `xmllint`, part of libxml2, to format the generated polygot XHTML5 markup.
|
||||||
|
- [sd](https://github.com/chmln/sdA) (for advanced multi-line regex operations, much of which exist to fix `xmllint`'s output)
|
||||||
|
|
||||||
|
I also apply static compression at max levels, using the following tools:
|
||||||
|
|
||||||
- [Efficient Compression Tool](https://github.com/fhanau/Efficient-Compression-Tool) It's like zopfli but more efficient and faster.
|
- [Efficient Compression Tool](https://github.com/fhanau/Efficient-Compression-Tool) It's like zopfli but more efficient and faster.
|
||||||
- Brotli (optional; set `NO_STATIC=1` to disable)
|
- Brotli
|
||||||
- POSIX utils: grep, find, etc.
|
|
||||||
|
|
||||||
To deploy:
|
To deploy:
|
||||||
|
|
||||||
- ssh
|
- rsync, with SSH and zstd support
|
||||||
- rsync
|
|
||||||
- libzstd
|
|
||||||
|
|
||||||
To lint:
|
To lint:
|
||||||
|
|
||||||
- stylelint
|
- stylelint, invoked using pnpm.
|
||||||
- csslint
|
- [lychee](https://github.com/lycheeverse/lychee), to check broken links.
|
||||||
- pnpm
|
- A very recent build of the w3c's [Nu HTML checker](https://github.com/validator/validator) to validate the HTML and XHTML.
|
||||||
- [lychee](https://github.com/lycheeverse/lychee)
|
- [jq](https://stedolan.github.io/jq/), to filter false-positives from the Nu HTML checker.
|
||||||
|
|
||||||
See the `Makefile` for details.
|
Build instructions
|
||||||
|
------------------
|
||||||
|
|
||||||
Design
|
- To just build the HTML: `make hugo`
|
||||||
------
|
- To build the polygot formatted HTML and XHTML: `make hugo xhtmlize`
|
||||||
|
- To lint and validate: `make hugo xhtmlize lint-local`
|
||||||
|
- To build everything and compress: `make hugo xhtmlize compress`
|
||||||
|
- To deploy the clearnet site and corresponding Tor hidden service: `make deploy-prod deploy-onion`
|
||||||
|
|
||||||
I made the site as inclusive as possible. Tested using multiple screen readers (Orca, TalkBack, Apple VoiceOver, Windows Narrator, NVDA), and I regularly test with the following browsers/engines. Testing in a browser does not imply any sort of endorsement; I just want to meet people where they're at.
|
`make` can parallelize only a little, since many jobs depend on previous jobs.
|
||||||
|
|
||||||
Desktop:
|
Compatibility
|
||||||
|
-------------
|
||||||
|
|
||||||
|
I made the site as inclusive as possible. Tested using multiple screen readers (Orca, TalkBack, Apple VoiceOver, Windows Narrator, NVDA), and I regularly test with the following browsers/engines. Testing in a browser does not imply any sort of endorsement; I just want to meet people where they're at and I want my site to be as robust as possible.
|
||||||
|
|
||||||
|
For all the listed options, I test "reading mode" whenever it's available. Most of my testing happens on Linux since that's my main OS, but I sometimes test on a Windows machine.
|
||||||
|
|
||||||
|
The main compatibility issue is a lack of support for `<details>`; the only non-mainstream engine to support it is Servo. The site is still perfectly usable without support for `<details>`; users will just be annoyed by pre-expanded toggle buttons that don't do anything.
|
||||||
|
|
||||||
|
### Desktop
|
||||||
|
|
||||||
|
Mainstream engines:
|
||||||
|
|
||||||
- Gecko: Nightly, Stable, ESR, and sometimes Pale Moon
|
- Gecko: Nightly, Stable, ESR, and sometimes Pale Moon
|
||||||
- the Tor Browser
|
- the Tor Browser
|
||||||
- Blink: latest Chromium snapshot, stable, and QtWebEngine
|
- Blink: latest Chromium snapshot, stable, and QtWebEngine
|
||||||
- WebKit: Webkit2GTK3
|
- WebKit, via Webkit2GTK3
|
||||||
|
|
||||||
|
Non-mainstream engines:
|
||||||
|
|
||||||
- NetSurf
|
- NetSurf
|
||||||
- SerenityOS Browser
|
- [The SerenityOS Browser](https://github.com/SerenityOS/serenity/tree/master/Userland/Libraries/LibWeb) (does not yet support ECDSA-based certs, so I test on my Tildeverse mirror). Known issue: SVG avatar doesn't render unless I view it in a new tab.
|
||||||
- Very old WebKit via rekonq (Qt4 QtWebKit)
|
- Very old WebKit via rekonq (Qt4 QtWebKit).
|
||||||
- KHTML
|
- KHTML (KF5), via Konqueror.
|
||||||
- Servo
|
- Servo
|
||||||
- Trident, if I have access to a Windows machine that has Edge with "IE Mode".
|
- Tkhtml, via Hv3 (no TLS 1.2, so I use a terminating proxy or localhost version)
|
||||||
|
|
||||||
For all the above options, I test "reading mode" whenever it's available.
|
Tested on a provisional basis, when I have access to a Windows machine:
|
||||||
|
|
||||||
Mobile:
|
- [Winternight Classic](https://github.com/ClassicNick/Crescent-Vine).
|
||||||
|
- IE 11.
|
||||||
|
- Even older WebKit, via Safari 5.1.7. Requires a TLS terminating proxy.
|
||||||
|
- Ancient Gecko, via NetScape Navigator. Requires a TLS terminating proxy.
|
||||||
|
|
||||||
|
Desktop screen readers tested:
|
||||||
|
|
||||||
|
- Orca
|
||||||
|
- NVDA
|
||||||
|
- Windows Narrator
|
||||||
|
- TODO: borrow someone's mac and test macOS VoiceOver.
|
||||||
|
|
||||||
|
### Mobile
|
||||||
|
|
||||||
- Android: Blink, Gecko, Tor Browser
|
- Android: Blink, Gecko, Tor Browser
|
||||||
- iOS WebKit: latest stable version, iOS 12, iOS 10 on an iPhone 5. Also test Reader Mode.
|
- iOS WebKit: latest stable version, iOS 12, iOS 10 on an iPhone 5. Also tested Reader Mode.
|
||||||
- TODO: try a KaiOS device.
|
- TODO: try a KaiOS device and Samsung Internet's dark mode.
|
||||||
|
|
||||||
Smart watches:
|
The site should work well even on viewports that are under 240 CSS pixels wide.
|
||||||
|
|
||||||
|
Mobile screen readers:
|
||||||
|
|
||||||
|
- TalkBack
|
||||||
|
- VoiceOver
|
||||||
|
- TODO: test KaiOS Readout
|
||||||
|
|
||||||
|
### Smart watches
|
||||||
|
|
||||||
- Borrowed an Apple Watch to try the embedded browser.
|
- Borrowed an Apple Watch to try the embedded browser.
|
||||||
- TODO: test on a Tizen or Wear OS device's browser.
|
- TODO: test on a Tizen or Wear OS device's browser (Samsung Internet is a popular choice)
|
||||||
|
|
||||||
Everything works well in all the above browsers.
|
## Accessibility
|
||||||
|
|
||||||
|
To my knowledge, this site meets all applicable WCAG 2.2 AA requirements.
|
||||||
|
|
||||||
|
This site meets all applicable WCAG 2.2 AAA requirements, with the following exceptions:
|
||||||
|
|
||||||
|
- SC 1.4.8 Visual Presentation: long article body text for articles should have an average character count per line below 80 characters. Some lines may exceed this limit. Text outside of article bodies has a longer line width.
|
||||||
|
- SC 2.4.9 Link Purpose (Link Only): I mostly follow this guideline, but there may be some exceptions. Link purpose in context is always clear, though.
|
||||||
|
- SC 3.1.5 Reading Level: the required reading ability often exceeds the lower secondary education level
|
||||||
|
- SC 3.1.6 Pronunciation: I do not yet provide pronunciation information.
|
||||||
|
|
||||||
|
I have only tested WCAG compliance in mainstream browser engines (Blink, Gecko, WebKit).
|
||||||
|
|
||||||
|
I also go further than WCAG in many aspects.
|
||||||
|
|
||||||
|
- Rather than follow SC 2.5.5's requirement to achieve a minimum tap target size of 44 by 44 pixels, I follow Google's more strict guidelines. These guidelines mandate that targets are at least 48-by-48 pixels, with no overlap against any other targets in a 56-by-56 pixel range.
|
||||||
|
- I ensure at least one such 56-by-56 pixel non-interactive region exists on the page, for users with hand tremors or or anyone who wants to tap the screen without clicking something.
|
||||||
|
- I only set custom colors in response to the `prefers-color-scheme: dark` media query. These custom colors pass APCA contrast ratios, all being close to the ideal lightness contrast of 90. They are also autism- and overstimulation-friendly colors: yellow links are significantly de-saturated to reduce harshness.
|
||||||
|
|
|
@ -338,7 +338,7 @@ pre {
|
||||||
/* center standalone images; same justification as
|
/* center standalone images; same justification as
|
||||||
* for centering the body contents. Also makes images easier to see
|
* for centering the body contents. Also makes images easier to see
|
||||||
* for people holding a device with one hand. */
|
* for people holding a device with one hand. */
|
||||||
picture > img {
|
div[itemprop="articleBody"] img {
|
||||||
display: block;
|
display: block;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
|
@ -8,7 +8,9 @@ description: "Seirdy's Home: personal website and blog for Rohan Kumar, A.K.A. S
|
||||||
sitemap:
|
sitemap:
|
||||||
- ChangeFreq: weekly
|
- ChangeFreq: weekly
|
||||||
- Priority: 0.9
|
- Priority: 0.9
|
||||||
|
stype: "WebSite"
|
||||||
---
|
---
|
||||||
|
<meta itemprop="url" content="https://seirdy.one" />
|
||||||
<div itemprop="author" itemscope="" itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="p-author author h-card vcard" id="seirdy">
|
<div itemprop="author" itemscope="" itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="p-author author h-card vcard" id="seirdy">
|
||||||
|
|
||||||
Seirdy’s Home
|
Seirdy’s Home
|
||||||
|
|
7
content/search.md
Normal file
7
content/search.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
outputs:
|
||||||
|
- html
|
||||||
|
title: Search
|
||||||
|
description: "Search seirdy.one."
|
||||||
|
layout: "search"
|
||||||
|
---
|
1
dynamic/README.txt
Normal file
1
dynamic/README.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Files in this directory represent dynamic pages, containing raw templates to be populated on the server side
|
28
dynamic/search-results.html
Normal file
28
dynamic/search-results.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<p>
|
||||||
|
{{ .TotalResults }} results
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
{{- range .Results }}
|
||||||
|
<li>
|
||||||
|
<a href="{{ .URL }}">
|
||||||
|
<h2>
|
||||||
|
{{ if .Title -}}
|
||||||
|
{{- .Title }}
|
||||||
|
{{ else -}}
|
||||||
|
{{- .URL }}
|
||||||
|
{{- end }}
|
||||||
|
</h2>
|
||||||
|
</a>
|
||||||
|
<p>{{ printf "%.200s" .Desc }}</p>
|
||||||
|
<p>
|
||||||
|
{{ $isMatch := false }}
|
||||||
|
{{ range .Frag }}
|
||||||
|
{{ if $isMatch }}<strong>{{ end -}}
|
||||||
|
{{ printf . }}
|
||||||
|
{{- if $isMatch }}</strong>{{ end }}
|
||||||
|
{{ $isMatch = (not $isMatch) }}
|
||||||
|
{{ end }}
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
{{- end }}
|
||||||
|
</ol>
|
|
@ -1,9 +1,13 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{- default "" .Site.LanguageCode }}" xml:lang="{{- default "" .Site.LanguageCode }}" prefix="og: https://ogp.me/ns# article: https://ogp.me/ns/article# cc: http://creativecommons.org/ns#">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{- default "" .Site.LanguageCode }}" xml:lang="{{- default "" .Site.LanguageCode }}" prefix="og: https://ogp.me/ns# article: https://ogp.me/ns/article# cc: http://creativecommons.org/ns#">
|
||||||
{{ partial "head.html" . -}}
|
{{ partial "head.html" . -}}
|
||||||
<body itemscope="" itemtype="https://schema.org/WebPage">
|
{{- $stype := "WebPage" -}}
|
||||||
|
{{- with .Params.stype -}}
|
||||||
|
{{- $stype = . -}}
|
||||||
|
{{- end -}}
|
||||||
|
<body itemscope="" itemtype="https://schema.org/{{ $stype }}">
|
||||||
{{ partial "header.html" . -}}
|
{{ partial "header.html" . -}}
|
||||||
{{- block "main" . }}{{- end -}}
|
{{- block "main" . }}{{- end -}}
|
||||||
{{ partialCached "footer.html" . }}
|
{{ partial "footer.html" . }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
12
layouts/_default/search.html
Normal file
12
layouts/_default/search.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{{ define "main" -}}
|
||||||
|
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
|
||||||
|
<main >
|
||||||
|
<h1>Search</h1>
|
||||||
|
<p role="note">This page is an unfinished work-in-progress.</p>
|
||||||
|
{{ partial "search.html" . }}
|
||||||
|
<hr />
|
||||||
|
<div itemprop="mainEntity" itemscope="" itemtype="https://schema.org/SearchResultsPage" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
|
||||||
|
{{ readFile "/dynamic/search-results.html" | safeHTML }}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{{ end }}
|
|
@ -3,7 +3,9 @@
|
||||||
<p>
|
<p>
|
||||||
Copyright <time itemprop="copyrightYear" datetime="{{now.Year}}">{{now.Year}}</time> {{ partial "indieweb-author.html" -}}
|
Copyright <time itemprop="copyrightYear" datetime="{{now.Year}}">{{now.Year}}</time> {{ partial "indieweb-author.html" -}}
|
||||||
</p>
|
</p>
|
||||||
{{ partial "search.html" }}
|
{{ if ne .Title "Search" -}}
|
||||||
|
{{- partial "search.html" -}}
|
||||||
|
{{- end -}}
|
||||||
<nav aria-label="site info">
|
<nav aria-label="site info">
|
||||||
<ul>
|
<ul>
|
||||||
<li itemprop="license" itemscope="" itemtype="https://schema.org/CreativeWork">
|
<li itemprop="license" itemscope="" itemtype="https://schema.org/CreativeWork">
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<form
|
<form
|
||||||
itemprop="potentialAction" itemscope="" itemtype="https://schema.org/SearchAction"
|
itemprop="potentialAction" itemscope="" itemtype="https://schema.org/SearchAction"
|
||||||
action="https://searchmysite.net/search/" method="get" role="search">
|
action="https://seirdy.one/search/" method="get" role="search">
|
||||||
<label for="search">
|
<label for="search" itemscope="" itemprop="target" itemtype="https://schema.org/EntryPoint">
|
||||||
Search this site (powered by <a rel="nofollow" href="https://searchmysite.net/">Search My Site</a>):
|
Search this site (powered by the <a rel="nofollow" href="https://searchmysite.net/">Search My Site</a> API):
|
||||||
|
<meta itemprop="urlTemplate" content="http://seirdy.one/search?q={q}" />
|
||||||
</label>
|
</label>
|
||||||
<div><!--We need the extra divs to serve as pseudo-table-cells.-->
|
<div><!--We need the extra divs to serve as pseudo-table-cells.-->
|
||||||
<input id="search" type="search" itemprop="query"
|
<input itemprop="query-input" id="search" type="search" required="" name="q" />
|
||||||
value="domain:seirdy.one " name="q" spellcheck="true" />
|
|
||||||
<div><input type="submit" value="search" /></div>
|
<div><input type="submit" value="search" /></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
{{ $favicon := resources.Get "/favicon.png" -}}
|
{{ $favicon := resources.Get "/favicon.png" -}}
|
||||||
{{- $favicon_base64 := $favicon.Content | base64Encode -}}
|
{{- $favicon_base64 := $favicon.Content | base64Encode -}}
|
||||||
|
{{- $favicon_bigpng := resources.Get "/favicon192.png" | resources.Fingerprint "md5" -}}
|
||||||
{{- $favicon_svg := resources.Get "/favicon.svg" | resources.Fingerprint "md5" -}}
|
{{- $favicon_svg := resources.Get "/favicon.svg" | resources.Fingerprint "md5" -}}
|
||||||
|
{{- if in site.BaseURL ".onion" -}}
|
||||||
<img itemprop="image" class="u-photo photo" width="16" height="16" alt=""
|
<img itemprop="image" class="u-photo photo" width="16" height="16" alt=""
|
||||||
{{ if in site.BaseURL ".onion" -}}
|
src="data:image/png;base64,{{ $favicon_base64 }}" />
|
||||||
src="data:image/png;base64,{{ $favicon_base64 }}"
|
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
src="{{ $favicon_svg.RelPermalink }}"
|
<picture itemprop="image">
|
||||||
{{- end }} />
|
<source srcset="{{ $favicon_svg.RelPermalink }}" type="image/svg+xml" />
|
||||||
|
<img class="u-photo photo" width="16" height="16" alt=""
|
||||||
|
src="{{ $favicon_bigpng.RelPermalink }}" />
|
||||||
|
</picture>
|
||||||
|
{{- end -}}
|
||||||
|
|
|
@ -13,6 +13,20 @@
|
||||||
.message == "Attribute “media” not allowed on element “meta” at this point."
|
.message == "Attribute “media” not allowed on element “meta” at this point."
|
||||||
and (.extract | test(" name=\"theme-color\""))
|
and (.extract | test(" name=\"theme-color\""))
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
( # Allow raw templates
|
||||||
|
(.url | test ("/search/index."))
|
||||||
|
and (
|
||||||
|
(.message == "Text not allowed in element “ol” in this context.")
|
||||||
|
or
|
||||||
|
(.message == "Bad value “{{ .URL }}” for attribute “href” on element “a”: Illegal character in path segment: “{” is not allowed.")
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
(.extract | test("{{"))
|
||||||
|
or
|
||||||
|
(.extract | test("}}"))
|
||||||
|
)
|
||||||
|
)
|
||||||
) | not
|
) | not
|
||||||
)
|
)
|
||||||
) | del(..|select(. == [])) | del(..|select(. == {})) | select(. != null)
|
) | del(..|select(. == [])) | del(..|select(. == {})) | select(. != null)
|
||||||
|
|
|
@ -34,7 +34,7 @@ sed 7d "$html_file" | xmllint --format --encode UTF-8 --noent - | sd '^\t' '' >"
|
||||||
| sd '<pre(?: tabindex="0")?>\n\t*<code ' '<pre tabindex="0"><code ' \
|
| sd '<pre(?: tabindex="0")?>\n\t*<code ' '<pre tabindex="0"><code ' \
|
||||||
| sd '(?:\n)?</code>\n(?:[\t\s]*)?</pre>' '</code></pre>' \
|
| sd '(?:\n)?</code>\n(?:[\t\s]*)?</pre>' '</code></pre>' \
|
||||||
| sd '</span>.span itemprop="familyName"' '</span> <span itemprop="familyName"' \
|
| sd '</span>.span itemprop="familyName"' '</span> <span itemprop="familyName"' \
|
||||||
| sd '(<img itemprop="image" class="u-photo photo"[^>]*/>)<span' '$1 <span' \
|
| sd '</picture><span itemprop="name" class="p-name fn n">' '</picture> <span itemprop="name" class="p-name fn n">' \
|
||||||
| sd '([a-z])<(data|time)' '$1 <$2'
|
| sd '([a-z])<(data|time)' '$1 <$2'
|
||||||
} >>"$xhtml_file"
|
} >>"$xhtml_file"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue