Compare commits

..

3 Commits

Author SHA1 Message Date
b4a1097845 buncha stuff 2023-08-16 21:45:48 -07:00
adc582116b wip sidenotes post 2023-08-15 11:48:07 -07:00
7d5c696fa7 start working on sidenotes post 2023-08-15 11:10:22 -07:00
14 changed files with 92 additions and 514 deletions

349
package-lock.json generated
View File

@@ -10,13 +10,10 @@
"devDependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.21",
"@sveltejs/kit": "next",
"hast-util-to-text": "^3.1.2",
"mdsvex": "^0.9.8",
"node-sass": "^6.0.1",
"svelte": "^3.42.6",
"svelte-preprocess": "^4.9.8",
"unist-util-find": "^2.0.0",
"unist-util-visit": "^5.0.0"
"svelte-preprocess": "^4.9.8"
}
},
"node_modules/@babel/code-frame": {
@@ -162,15 +159,6 @@
}
}
},
"node_modules/@types/hast": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
"integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
"dev": true,
"dependencies": {
"@types/unist": "^2"
}
},
"node_modules/@types/minimist": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
@@ -1445,36 +1433,6 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
},
"node_modules/hast-util-is-element": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz",
"integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==",
"dev": true,
"dependencies": {
"@types/hast": "^2.0.0",
"@types/unist": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-to-text": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz",
"integrity": "sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==",
"dev": true,
"dependencies": {
"@types/hast": "^2.0.0",
"@types/unist": "^2.0.0",
"hast-util-is-element": "^2.0.0",
"unist-util-find-after": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -1731,12 +1689,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash.iteratee": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz",
"integrity": "sha512-yv3cSQZmfpbIKo4Yo45B1taEvxjNvcpF1CEOc0Y6dEyvhPIfEJE3twDwPgWTPQubcSgXyBwBKG6wpQvWMDOf6Q==",
"dev": true
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -2992,109 +2944,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/unist-util-find": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unist-util-find/-/unist-util-find-2.0.0.tgz",
"integrity": "sha512-I4NH8M2r7B9pGNXl41fftwCCi/WhG50RUdZDYcpEmiQEgHUYtfWpcCX4/R6s4XtK0ztxUSwC6u9sztlnDQAoaA==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"lodash.iteratee": "^4.0.0",
"unist-util-visit": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find-after": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz",
"integrity": "sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find-after/node_modules/unist-util-is": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find/node_modules/unist-util-is": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find/node_modules/unist-util-visit": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
"integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0",
"unist-util-visit-parents": "^5.1.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find/node_modules/unist-util-visit-parents": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
"integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
"dev": true,
"dependencies": {
"@types/unist": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-is/node_modules/@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
@@ -3108,47 +2957,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
"dev": true,
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0",
"unist-util-visit-parents": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit-parents": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
"dev": true,
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit-parents/node_modules/@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
},
"node_modules/unist-util-visit/node_modules/@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -3604,15 +3412,6 @@
"svelte-hmr": "^0.14.11"
}
},
"@types/hast": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
"integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
"dev": true,
"requires": {
"@types/unist": "^2"
}
},
"@types/minimist": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
@@ -4513,28 +4312,6 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
},
"hast-util-is-element": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz",
"integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==",
"dev": true,
"requires": {
"@types/hast": "^2.0.0",
"@types/unist": "^2.0.0"
}
},
"hast-util-to-text": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz",
"integrity": "sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==",
"dev": true,
"requires": {
"@types/hast": "^2.0.0",
"@types/unist": "^2.0.0",
"hast-util-is-element": "^2.0.0",
"unist-util-find-after": "^4.0.0"
}
},
"hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -4748,12 +4525,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash.iteratee": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz",
"integrity": "sha512-yv3cSQZmfpbIKo4Yo45B1taEvxjNvcpF1CEOc0Y6dEyvhPIfEJE3twDwPgWTPQubcSgXyBwBKG6wpQvWMDOf6Q==",
"dev": true
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -5681,87 +5452,6 @@
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"dev": true
},
"unist-util-find": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unist-util-find/-/unist-util-find-2.0.0.tgz",
"integrity": "sha512-I4NH8M2r7B9pGNXl41fftwCCi/WhG50RUdZDYcpEmiQEgHUYtfWpcCX4/R6s4XtK0ztxUSwC6u9sztlnDQAoaA==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0",
"lodash.iteratee": "^4.0.0",
"unist-util-visit": "^4.0.0"
},
"dependencies": {
"unist-util-is": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0"
}
},
"unist-util-visit": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
"integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0",
"unist-util-visit-parents": "^5.1.1"
}
},
"unist-util-visit-parents": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
"integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0"
}
}
}
},
"unist-util-find-after": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz",
"integrity": "sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0"
},
"dependencies": {
"unist-util-is": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0"
}
}
}
},
"unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
"dev": true,
"requires": {
"@types/unist": "^3.0.0"
},
"dependencies": {
"@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
}
}
},
"unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
@@ -5771,43 +5461,6 @@
"@types/unist": "^2.0.2"
}
},
"unist-util-visit": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
"dev": true,
"requires": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0",
"unist-util-visit-parents": "^6.0.0"
},
"dependencies": {
"@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
}
}
},
"unist-util-visit-parents": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
"dev": true,
"requires": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0"
},
"dependencies": {
"@types/unist": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
"dev": true
}
}
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View File

@@ -12,10 +12,7 @@
"mdsvex": "^0.9.8",
"node-sass": "^6.0.1",
"svelte": "^3.42.6",
"svelte-preprocess": "^4.9.8",
"unist-util-visit": "^5.0.0",
"unist-util-find": "^2.0.0",
"hast-util-to-text": "^3.1.2"
"svelte-preprocess": "^4.9.8"
},
"type": "module"
}

View File

@@ -34,8 +34,9 @@
}
</style>
<p>
<span class="drop-cap">{initial}</span>
{#if remainder.length}
<span class="first-word" style:--shift={shift}>{remainder}</span>
{/if}
<slot></slot>
</p>

View File

@@ -1,52 +0,0 @@
<script>
export let level;
export let id = '';
const tag = `h${level}`;
</script>
<style>
a {
/* Works better to set the size here for line-height reasons */
font-size: 0.9em;
color: hsl(0, 0%, 50%);
}
a:hover {
border-bottom: 0.05em solid currentcolor;
}
svg {
width: 1em;
}
.before {
display: none;
margin-right: 0.5rem;
margin-left: calc(-1em - 0.5rem);
}
@media(min-width: 58rem) {
.before {
display: inline;
}
.after {
display: none;
}
}
</style>
<svelte:element this={tag} {id} class="h">
<a href="#{id}" class="before">
<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.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" />
</svg></a><span> <!-- Looks ugly but necessary to get rid of spurious whitespace -->
<slot></slot>
</span>
<!-- Icon from https://heroicons.com/ -->
<a href="#{id}" class="after">
<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.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" />
</svg>
</a>
</svelte:element>

View File

@@ -1,7 +1,7 @@
<script context="module">
import { onMount } from 'svelte';
import { formatDate } from './datefmt.js';
import { makeSlug } from '$lib/utils.js';
import { makeSlug } from '$lib/slug.js';
import Link from './Link.svelte';
export { Link as a };

View File

@@ -0,0 +1,20 @@
<script>
import Step from './Step.svelte';
import {onMount} from 'svelte';
let frame;
onMount(() => {
frame.setAttribute('srcdoc', frame.innerHTML);
})
</script>
<iframe bind:this={frame}>
<html>
<head></head>
<body>
<Step />
<p>Goodbye world!</p>
</body>
</html>
</iframe>

View File

@@ -0,0 +1,7 @@
<script>
let count = 0;
</script>
<p>hello world!</p>
<button on:click={() => count++}>Increment</button>
<p>The count is: {count}</p>

50
src/lib/slug.js Normal file
View File

@@ -0,0 +1,50 @@
const nonAlphaNum = /[^A-Za-z0-9\-]/g;
const space = /\s/g
export function makeSlug(text) {
return text
.toLowerCase()
.replace(space, '-')
.replace(nonAlphaNum, '')
}
function apply(node, types, fn) {
if (typeof types === 'string') {
types = new Set([types]);
}
else if (!(types instanceof Set)) {
types = new Set(types)
console.log(types)
}
if (types.has(node.type)) {
fn(node);
}
if ('children' in node) {
for (let child of node.children) {
apply(child, types, fn);
}
}
}
function getTextContent(node) {
let segments = [];
apply(node, 'text', textNode => {
// skip all-whitespace strings
if (textNode.value.match(/^\s+$/)) return;
segments.push(textNode.value.trim());
});
return segments.join(' ');
}
export default function slug() {
return (tree) => {
apply(tree, 'element', e => {
if (e.tagName.match(/h[1-6]/)) {
let text = getTextContent(e);
e.properties.id = makeSlug(text);
}
})
}
}

View File

@@ -1,8 +0,0 @@
const nonAlphaNum = /[^A-Za-z0-9\-]/g;
const space = /\s+/g;
export function makeSlug(text) {
return text
.toLowerCase()
.replace(space, '-')
.replace(nonAlphaNum, '');
}

View File

@@ -1,90 +0,0 @@
import { visit, CONTINUE, EXIT, SKIP, } from 'unist-util-visit';
import { find } from 'unist-util-find';
import { toText } from 'hast-util-to-text';
import { makeSlug } from '../lib/utils.js';
export function localPlugins() {
let printed = false;
return (tree, vfile) => {
const needsDropcap = vfile.data.fm.dropcap !== false
let dropcapAdded = false;
let moduleScript;
let imports = new Set();
if (needsDropcap) {
imports.add("import Dropcap from '$lib/Dropcap.svelte';");
}
visit(tree, node => {
// add slugs to headings
if (isHeading(node)) {
processHeading(node);
imports.add("import Heading from '$lib/Heading.svelte';");
return SKIP;
}
// mdsvex adds a <script context="module"> so we just hijack that for our own purposes
if (isModuleScript(node)) {
moduleScript = node;
}
// convert first letter/word of first paragraph to <Dropcap word="{whatever}">
if (needsDropcap && !dropcapAdded && isParagraph(node)) {
addDropcap(node);
dropcapAdded = true;
return SKIP;
}
});
// insert our imports at the top of the `<script context="module">` tag
if (imports.size > 0) {
const script = moduleScript.value;
// split the script where the opening tag ends
const i = script.indexOf('>');
const openingTag = script.slice(0, i + 1);
const remainder = script.slice(i + 1);
// mdvsex uses tabs so we will as well
const importScript = Array.from(imports).join('\n\t');
moduleScript.value = `${openingTag}\n\t${importScript}${remainder}`;
}
}
}
function processHeading(node) {
const level = node.tagName.slice(1);
node.tagName = 'Heading';
node.properties.level = level;
node.properties.id = makeSlug(toText(node));
}
function addDropcap(par) {
let txtNode = find(par, {type: 'text'});
const i = txtNode.value.search(/\s/);
const firstWord = txtNode.value.slice(0, i);
const remainder = txtNode.value.slice(i);
par.children.unshift({
type: 'raw',
value: `<Dropcap word="${firstWord}" />`,
});
txtNode.value = remainder;
}
function isHeading(node) {
return node.type === 'element' && node.tagName.match(/h[1-6]/);
}
function isModuleScript(node) {
return node.type === 'raw' && node.value.match(/^<script context="module">/);
}
function isParagraph(node) {
return node.type === 'element' && node.tagName === 'p';
}

View File

@@ -3,7 +3,6 @@ title: Imagining A Passwordless Future
description: Can we replace passwords with something more user-friendly?
date: 2021-04-30
draft: true
dropcap: false
---
<script>
import Sidenote from '$lib/Sidenote.svelte';

View File

@@ -4,8 +4,10 @@ description: An entirely-too-detailed dive into how I implemented sidenotes for
date: 2023-08-14
---
<script>
import Dropcap from '$lib/Dropcap.svelte';
import Sidenote from '$lib/Sidenote.svelte';
import UnstyledSidenote from '$lib/UnstyledSidenote.svelte';
import Frame from '$lib/projects/sidenotes/Frame.svelte';
</script>
<style>
@@ -62,7 +64,7 @@ date: 2023-08-14
}
</style>
One of my major goals when building this blog was to have sidenotes. I've always been a fan of sidenotes on the web, because the most comfortable reading width for a column of text is <em>far</em> less than the absurd amounts of screen width we tend to have available, and what else are we going to use it for?<Sidenote>Some sites use it for ads, of course, which is yet another example of how advertising ruins everything.</Sidenote>
<Dropcap word="One">of my major goals when building this blog was to have sidenotes. I've always been a fan of sidenotes on the web, because the most comfortable reading width for a column of text is <em>far</em> less than the absurd amounts of screen width we tend to have available, and what else are we going to use it for?<Sidenote>Some sites use it for ads, of course, which is yet another example of how advertising ruins everything.</Sidenote></Dropcap>
Footnotes don't really work on the web the way they do on paper, since the web doesn't have page breaks. You _can_ stick your footnotes in a floating box at the bottom of the page, so they're visible at the bottom of the text just like they would be on a printed page, but this sacrifices precious vertical space.<Sidenote>On mobile, it's _horizontal_ space that's at a premium, so I do use this approach there. Although I'm a pretty heavy user of sidenotes, so I have to make them toggleable as well or they'd fill up the entire screen.</Sidenote> Plus, you usually end up with the notes further away from the point of divergence than they would be as sidenotes anyway.

View File

@@ -4,11 +4,12 @@ description: They're more similar than they are different, but they say the most
date: 2023-06-29
---
<script>
import Dropcap from '$lib/Dropcap.svelte';
import Sidenote from '$lib/Sidenote.svelte';
</script>
Recently I've had a chance to get to know Vue a bit. Since my frontend framework of choice has previously been Svelte (this blog is built in Svelte, for instance) I was naturally interested in how they compared.
<Dropcap word="Recently">I've had a chance to get to know Vue a bit. Since my frontend framework of choice has previously been Svelte (this blog is built in Svelte, for instance) I was naturally interested in how they compared.</Dropcap>
Of course, this is only possible because Vue and Svelte are really much more similar than they are different. Even among frontend frameworks, they share a lot of the same basic ideas and high-level concepts, which means that we get to dive right into the nitpicky details and have fun debating `bind:attr={value}` versus `:attr="value"`. In the meantime, a lot of the building blocks are basically the same or at least have equivalents, such as:
* Single-file components with separate sections for markup, style, and logic

View File

@@ -1,9 +1,7 @@
import { mdsvex } from 'mdsvex';
import staticAdapter from '@sveltejs/adapter-static';
import svp from 'svelte-preprocess';
// import slug from './src/lib/slug.js';
// import { addDropcaps } from './src/lib/dropcapify.js';
import { localPlugins } from './src/plugins/rehype.js';
import slug from './src/lib/slug.js';
const config = {
@@ -11,7 +9,7 @@ const config = {
preprocess: [
mdsvex({
layout: './src/lib/Post.svelte',
rehypePlugins: [localPlugins],
rehypePlugins: [slug],
}),
svp.scss(),
],