404 lines
9.4 KiB
XML
404 lines
9.4 KiB
XML
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|||
|
|
<!--
|
|||
|
|
|
|||
|
|
# Pretty Atom Feed
|
|||
|
|
|
|||
|
|
Based on "Pretty RSS Feed": https://github.com/genmon/aboutfeeds/issues/26
|
|||
|
|
|
|||
|
|
Styles an Atom feed, making it friendly for humans viewers, and adds a link
|
|||
|
|
to aboutfeeds.com for new user onboarding. See it in action:
|
|||
|
|
|
|||
|
|
https://nicolas-hoizey.com/feeds/all.xml
|
|||
|
|
|
|||
|
|
-->
|
|||
|
|
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|||
|
|
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|||
|
|
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
|
|||
|
|
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
|
|||
|
|
<xsl:template match="/">
|
|||
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
|||
|
|
<head>
|
|||
|
|
<title>feed | <xsl:value-of select="atom:feed/atom:title"/></title>
|
|||
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|||
|
|
<style>:root {
|
|||
|
|
color-scheme: light dark;
|
|||
|
|
|
|||
|
|
--font-family: 'Atkinson Hyperlegible Next', sans-serif;
|
|||
|
|
--font-family-code: 'Atkinson Hyperlegible Mono', monospace;
|
|||
|
|
|
|||
|
|
--color-dark: #2e303e;
|
|||
|
|
--color-dark-alt: #3c3f52;
|
|||
|
|
--color-light: #ebeeef;
|
|||
|
|
--color-light-alt: #dbe1e3;
|
|||
|
|
|
|||
|
|
--color-teal-dark: #18737b;
|
|||
|
|
--color-teal-light: #25b0bc;
|
|||
|
|
--color-pink-dark: #94195d;
|
|||
|
|
--color-pink-light: #ee9fcb;
|
|||
|
|
|
|||
|
|
--color-shadow: rgba(2, 10, 40, .25);
|
|||
|
|
|
|||
|
|
/* Used for syntax highlighting */
|
|||
|
|
--color-red-light: #f195aa;
|
|||
|
|
--color-orange-light: #fab795;
|
|||
|
|
--color-yellow-light: #fbe6bc;
|
|||
|
|
--color-green-light: #29d398;
|
|||
|
|
--color-blue-light: #26bbd9;
|
|||
|
|
--color-purple-light: #ddaeea;
|
|||
|
|
--color-grey-light: #b9c3c6;
|
|||
|
|
|
|||
|
|
--color-red-dark: #991433;
|
|||
|
|
--color-orange-dark: #883206;
|
|||
|
|
--color-yellow-dark: #6a4906;
|
|||
|
|
--color-green-dark: #125940;
|
|||
|
|
--color-blue-dark: #125663;
|
|||
|
|
--color-purple-dark: #722999;
|
|||
|
|
--color-grey-dark: #4a4b64;
|
|||
|
|
|
|||
|
|
--color-text: light-dark(var(--color-dark), var(--color-light));
|
|||
|
|
--color-bg: light-dark(var(--color-light), var(--color-dark));
|
|||
|
|
|
|||
|
|
--color-text-alt: light-dark(var(--color-dark-alt), var(--color-light-alt));
|
|||
|
|
--color-bg-alt: light-dark(var(--color-light-alt), var(--color-dark-alt));
|
|||
|
|
|
|||
|
|
--color-teal: light-dark(var(--color-teal-dark), var(--color-teal-light));
|
|||
|
|
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
|
|||
|
|
|
|||
|
|
--color-red: light-dark(var(--color-red-dark), var(--color-red-light));
|
|||
|
|
--color-orange: light-dark(var(--color-orange-dark), var(--color-orange-light));
|
|||
|
|
--color-yellow: light-dark(var(--color-yellow-dark), var(--color-yellow-light));
|
|||
|
|
--color-green: light-dark(var(--color-green-dark), var(--color-green-light));
|
|||
|
|
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
|
|||
|
|
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
|
|||
|
|
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Base */
|
|||
|
|
|
|||
|
|
* {
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
font-family: var(--font-family);
|
|||
|
|
color: var(--color-text);
|
|||
|
|
background-color: var(--color-bg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
main {
|
|||
|
|
width: 60vw;
|
|||
|
|
max-width: 1000px;
|
|||
|
|
margin: 0 auto;
|
|||
|
|
scroll-margin-top: 7rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 1050px) {
|
|||
|
|
main {
|
|||
|
|
width: 75vw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 650px) {
|
|||
|
|
main {
|
|||
|
|
width: 92vw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Headers */
|
|||
|
|
h1, h2, h3, h4, h5, h6 {
|
|||
|
|
line-height: 1.25;
|
|||
|
|
color: var(--color-teal);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
margin-top: 3rem;
|
|||
|
|
font-size: 3.5rem;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h2, h3, h4, h5, h6 {
|
|||
|
|
scroll-margin-top: 5rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h2 {
|
|||
|
|
margin-top: 2rem;
|
|||
|
|
font-size: 2.2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h3 {
|
|||
|
|
margin-top: 1.5rem;
|
|||
|
|
font-size: 1.6rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 650px) {
|
|||
|
|
h1 { font-size: 2.8rem; }
|
|||
|
|
h2 { font-size: 1.8rem; }
|
|||
|
|
h3 { font-size: 1.35rem; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h4, h5, h6 {
|
|||
|
|
margin-top: 1rem;
|
|||
|
|
font-size: 1.2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Images */
|
|||
|
|
img {
|
|||
|
|
display: block;
|
|||
|
|
max-width: 100%;
|
|||
|
|
height: auto;
|
|||
|
|
border-radius: 1rem;
|
|||
|
|
margin: 0 auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Paragraphs */
|
|||
|
|
p {
|
|||
|
|
margin: 1.25rem 0;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
strong,
|
|||
|
|
b {
|
|||
|
|
font-weight: 900;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Links */
|
|||
|
|
a {
|
|||
|
|
color: var(--color-text);
|
|||
|
|
border-radius: .25rem;
|
|||
|
|
text-decoration: underline;
|
|||
|
|
text-decoration-style: solid;
|
|||
|
|
text-decoration-thickness: .2em;
|
|||
|
|
text-decoration-color: var(--color-teal);
|
|||
|
|
transition: text-decoration-thickness .5s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
a:focus-visible {
|
|||
|
|
text-decoration: none;
|
|||
|
|
outline: .15rem solid var(--color-teal);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (any-hover: hover) {
|
|||
|
|
a:hover {
|
|||
|
|
text-decoration-thickness: .4em;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
a:active {
|
|||
|
|
text-decoration-thickness: .4em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Heading anchors */
|
|||
|
|
a.ha,
|
|||
|
|
span.ha-placeholder {
|
|||
|
|
color: var(--color-pink);
|
|||
|
|
font-size: .8em;
|
|||
|
|
vertical-align: .1em;
|
|||
|
|
}
|
|||
|
|
span.ha-placeholder {
|
|||
|
|
opacity: .55;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Lists */
|
|||
|
|
::marker {
|
|||
|
|
color: var(--color-pink);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ul, ol, dl, li {
|
|||
|
|
margin-left: 1rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 650px) {
|
|||
|
|
ul, ol, dl {
|
|||
|
|
margin-left: 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
li {
|
|||
|
|
line-height: 1.2 5;
|
|||
|
|
margin-top: .65rem;
|
|||
|
|
margin-bottom: .65rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
li ul, li ol {
|
|||
|
|
margin: .5rem 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dt {
|
|||
|
|
font-weight: 900;
|
|||
|
|
margin-top: .5rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dd {
|
|||
|
|
margin-left: 2rem;
|
|||
|
|
margin-bottom: .75rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Blockquotes */
|
|||
|
|
blockquote {
|
|||
|
|
margin: .5rem 0;
|
|||
|
|
padding: 0 1rem;
|
|||
|
|
border-radius: .25rem 1rem 1rem .25rem;
|
|||
|
|
line-height: 1.25;
|
|||
|
|
border-left: .5rem solid var(--color-pink);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
blockquote,
|
|||
|
|
blockquote p,
|
|||
|
|
blockquote ol,
|
|||
|
|
blockquote ul {
|
|||
|
|
background-color: var(--color-bg-alt);
|
|||
|
|
padding: .5rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
blockquote p {
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Tables */
|
|||
|
|
table {
|
|||
|
|
width: 100%;
|
|||
|
|
border-spacing: 0; /* border collapse doesn't play nice with radii */
|
|||
|
|
border-radius: .3rem;
|
|||
|
|
border: thin solid var(--color-pink);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
th {
|
|||
|
|
color: var(--color-bg);
|
|||
|
|
background-color: var(--color-pink);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
th code {
|
|||
|
|
color: var(--color-text); /* Yes, I actually do this somewhere */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
th, td {
|
|||
|
|
padding: .5rem;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
tr:nth-child(even) { background-color: var(--color-bg-alt); }
|
|||
|
|
th:not(:first-child) { border-left: thin solid var(--color-bg); }
|
|||
|
|
th:first-child { border-top-left-radius: .25rem; }
|
|||
|
|
th:last-child { border-top-right-radius: .25rem; }
|
|||
|
|
td:not(:first-child) { border-left: thin solid var(--color-pink); }
|
|||
|
|
|
|||
|
|
/* Times */
|
|||
|
|
time {
|
|||
|
|
color: var(--color-grey);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Horizontal rules */
|
|||
|
|
hr {
|
|||
|
|
border: .25rem solid var(--color-pink);
|
|||
|
|
margin: 2rem 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Used on home, reference, gallery pages */
|
|||
|
|
.centered {
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Currently only used for resume, but it's generalizable */
|
|||
|
|
.upper {
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
<style>main {
|
|||
|
|
margin-bottom: 2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.rss-explainer {
|
|||
|
|
background: var(--color-bg-alt);
|
|||
|
|
padding: 1rem;
|
|||
|
|
margin-block: 1rem;
|
|||
|
|
border-radius: .5rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.rss-explainer p {
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.rss-explainer p + p {
|
|||
|
|
margin-top: 1.25rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.feed-url {
|
|||
|
|
font-family: var(--font-family-code);
|
|||
|
|
font-size: .9rem;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p:has(small) {
|
|||
|
|
display: block;
|
|||
|
|
margin: .25rem 0 0 .75rem;
|
|||
|
|
color: var(--color-grey);
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<main>
|
|||
|
|
<div class="rss-explainer">
|
|||
|
|
<p>
|
|||
|
|
<strong>This is a web feed,</strong> also known as an RSS or Atom feed. <strong>Subscribe</strong>
|
|||
|
|
by copying the URL below or from the address bar into your newsreader.
|
|||
|
|
</p>
|
|||
|
|
<p class="feed-url">https://leecat.art/feed.xml</p>
|
|||
|
|
<p>
|
|||
|
|
Visit <a href="https://aboutfeeds.com">About Feeds</a> to get started with newsreaders and subscribing. It’s free.
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
<h1>
|
|||
|
|
<!-- https://commons.wikimedia.org/wiki/File:Feed-icon.svg -->
|
|||
|
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="vertical-align: text-bottom; width: 1.2em; height: 1.2em;" id="RSSicon" viewBox="0 0 256 256" role="presentation">
|
|||
|
|
<defs>
|
|||
|
|
<linearGradient x1="0.085" y1="0.085" x2="0.915" y2="0.915" id="RSSg">
|
|||
|
|
<stop offset="0.0" stop-color="#E3702D"/><stop offset="0.1071" stop-color="#EA7D31"/>
|
|||
|
|
<stop offset="0.3503" stop-color="#F69537"/><stop offset="0.5" stop-color="#FB9E3A"/>
|
|||
|
|
<stop offset="0.7016" stop-color="#EA7C31"/><stop offset="0.8866" stop-color="#DE642B"/>
|
|||
|
|
<stop offset="1.0" stop-color="#D95B29"/>
|
|||
|
|
</linearGradient>
|
|||
|
|
</defs>
|
|||
|
|
<rect width="256" height="256" rx="55" ry="55" x="0" y="0" fill="#CC5D15"/>
|
|||
|
|
<rect width="246" height="246" rx="50" ry="50" x="5" y="5" fill="#F49C52"/>
|
|||
|
|
<rect width="236" height="236" rx="47" ry="47" x="10" y="10" fill="url(#RSSg)"/>
|
|||
|
|
<circle cx="68" cy="189" r="24" fill="#FFF"/>
|
|||
|
|
<path d="M160 213h-34a82 82 0 0 0 -82 -82v-34a116 116 0 0 1 116 116z" fill="#FFF"/>
|
|||
|
|
<path d="M184 213A140 140 0 0 0 44 73 V 38a175 175 0 0 1 175 175z" fill="#FFF"/>
|
|||
|
|
</svg>
|
|||
|
|
|
|||
|
|
feed preview: <xsl:value-of select="atom:feed/atom:title"/>
|
|||
|
|
</h1>
|
|||
|
|
<p><xsl:value-of select="atom:feed/atom:description"/></p>
|
|||
|
|
<p>This preview only shows titles, but the actual feed contains the full content.</p>
|
|||
|
|
<p><a>
|
|||
|
|
<xsl:attribute name="href">
|
|||
|
|
<xsl:value-of select="/atom:feed/atom:link[not(@rel)]/@href"/>
|
|||
|
|
</xsl:attribute>
|
|||
|
|
Visit website →
|
|||
|
|
</a></p>
|
|||
|
|
<h2>recent items</h2>
|
|||
|
|
<xsl:apply-templates select="atom:feed/atom:entry" />
|
|||
|
|
</main>
|
|||
|
|
</body>
|
|||
|
|
</html>
|
|||
|
|
</xsl:template>
|
|||
|
|
<xsl:template match="atom:feed/atom:entry">
|
|||
|
|
<div>
|
|||
|
|
<h3>
|
|||
|
|
<a>
|
|||
|
|
<xsl:attribute name="href">
|
|||
|
|
<xsl:value-of select="atom:link/@href"/>
|
|||
|
|
</xsl:attribute>
|
|||
|
|
<xsl:value-of select="atom:title"/>
|
|||
|
|
</a>
|
|||
|
|
</h3>
|
|||
|
|
<p><small>
|
|||
|
|
Published: <xsl:value-of select="atom:updated" />
|
|||
|
|
</small></p>
|
|||
|
|
</div>
|
|||
|
|
</xsl:template>
|
|||
|
|
</xsl:stylesheet>
|