initial feed implementation

This commit is contained in:
2023-09-04 22:07:58 -07:00
parent a28ee8b2f0
commit 7fb1f05a1e
17 changed files with 243 additions and 38 deletions

View File

@ -13,6 +13,9 @@
export const description = '';
export const draft = false;
export let toc = null;
export let prev = null;
export let next = null;
</script>
<style>
@ -46,7 +49,6 @@
grid-column: 2 / 3;
margin-bottom: 2rem;
display: flex;
justify-content: space-between;
}
hr {
@ -101,18 +103,23 @@
<hr>
<div class="footer">
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" />
</svg>
Previous
</a>
{#if prev}
<a href="/{prev}" data-sveltekit-preload-data="hover">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" />
</svg>
Previous
</a>
{/if}
<a href="#">
Next
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
</a>
{#if next}
<!-- we use margin-left rather than justify-content so it works regardless of whether the "previous" link exists -->
<a href="/{next}" style="margin-left: auto;" data-sveltekit-preload-data="hover">
Next
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
</a>
{/if}
</div>
</div>
</div>

View File

@ -23,7 +23,7 @@
}
.sidenote:before {
content: counter(sidenote) " ";
content: var(--sidenote-index, counter(sidenote)) " ";
/* absolute positioning puts it at the top-left corner of the sidenote, overlapping with the content
(because the sidenote is floated it counts as a positioned parent, I think) */
position: absolute;
@ -46,7 +46,7 @@
.sidenote {
--gap: 2rem;
--sidenote-width: min(14rem, calc(50vw - var(--gap) - var(--content-width) / 2));
--sidenote-width: min(16rem, calc(50vw - var(--gap) - 1rem - var(--content-width) / 2));
width: var(--sidenote-width);
hyphens: auto;
position: relative;

View File

@ -11,7 +11,6 @@
let currentSubheadingSlug = null;
function setCurrentHeading() {
const start = performance.now();
for (const h of headings) {
const yPos = h.getBoundingClientRect().y;
if (yPos > (window.innerHeight / 3)) {
@ -25,8 +24,6 @@
currentSubheadingSlug = h.id
}
}
const end = performance.now();
console.log(`Elapsed: ${end - start}`);
}
onMount (() => {

94
src/lib/xml.js Normal file
View File

@ -0,0 +1,94 @@
// const Node = {
// addChild(child) {
// this.children.push(child);
// return child;
// }
// }
export function tag(name, attrs, children) {
return {
type: 'tag',
tag: name,
attrs: attrs || {},
children: children || [],
addTag(name, attrs, children) {
const child = tag(name, attrs, children);
this.children.push(child);
return child;
},
};
}
export function text(content) {
return {
type: 'text',
text: content,
};
}
export function serialize(node, depth) {
if (!depth) {
depth = 0;
}
const indent = ' '.repeat(depth * 4);
let fragments = [];
// version tag, if this is the top level
if (depth === 0) {
fragments.push('<?xml version="1.0" encoding="UTF-8"?>\n')
}
fragments.push(`${indent}<${node.tag}`);
// this happens if there are multiple text nodes within the same parent
if (node.type === 'text') {
return `${indent}${escape(node.text)}`;
}
if (node.children === undefined) {
console.log(node);
}
// opening tag <element attr="value">
for (const attr in node.attrs) {
fragments.push(` ${attr}="${node.attrs[attr]}"`);
}
if (node.children.length === 0) {
fragments.push(' />');
return fragments.join('');
}
fragments.push('>');
// if the only child is a single text node, skip recursion and just dump contents directly
if (node.children.length === 1 && node.children[0].type === 'text') {
const text = escape(node.children[0].text);
fragments.push(text);
}
// otherwise, start a new line for each child node, then recurse
else {
for (const child of node.children) {
fragments.push('\n');
fragments.push(serialize(child, depth + 1));
}
// no need to verify that there were children, we already did that
fragments.push(`\n${indent}`);
}
fragments.push(`</${node.tag}>`);
return fragments.join('');
}
function escape(text) {
// we aren't going to bother with escaping attributes, so we won't worry about quotes
return text
.replaceAll('&', '&amp;')
.replaceAll('<', '&gt;')
.replaceAll('>', '&lt;');
}