85 lines
3.5 MiB
HTML
85 lines
3.5 MiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html lang="en"><head><script src="/___vscode_livepreview_injected_script" type="text/javascript"></script>
|
|||
|
<meta charset="utf-8" content="width=device-width, initial-scale=1"/>
|
|||
|
<link href="data:image/avif;base64,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
|
|||
|
<title>This page is portable</title>
|
|||
|
<link href="data:text/css; charset=UTF-8;base64,QGZvbnQtZmFjZSB7CiAgICAgICAgLyogZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcnlhbm9hc2lzL25lcmQtZm9udHMvdHJlZS9tYXN0ZXIvcGF0Y2hlZC1mb250cy9GaXJhQ29kZSAqLwogICAgICAgIGZvbnQtZmFtaWx5OiAiRmlyYUNvZGUiOwogICAgICAgIHNyYzogJ0ZpcmFDb2RlJywgdXJsKCdkYXRhOmZvbnQvd29mZjI7YmFzZTY0LGQwOUdNZ0FCQUFBQURtNmtBQklBQUFBZ3h4UUFEbTR6QUFZQWd3QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHb05ZRzRHUlFCeUMrV0lHWUQ5UVprVmtoRGdBeURnSWdTZ0puQlVSQ0Fydm9YVGE5ZzBCTmdJa0E0R3ZaZ3VDMzBBQUJDQUZrRnNIaXMwR0RJRldteklBRzEzQmcrSFB2WGVBNGo1bDY4d1FxaE0wSTF1Q3licVkyU3NVbWw3UmZ6N0pwcWFIbFB5TVFxRjNyWitlZkhpV1BOUEhKM3p4SmoxUVlsSzNPdnN4SWdlZ3FpcnVoK2NUU0l6dDlvRkxZTVlqcW1wV2ZZM3d0Z0dsejRNaHN2Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9kOHArbjNzMTc3L3p4dkdYbTNabjVXN1lmQ0NGQVNJQWZFc0tTc0Jzd3JDRWJhR1NOeUJJaUNvSkJRRnR0RWJXMmFtdlJscnEwVm11MXRiYTczUW1HclBOSjR0T2dXUjdTd3BiSlZpajNlWlpXMHpSTkxmbWE4L0F1cTdlMHBtbVJ0cldqSTJua3FIWVlxaVdkeTRUbE51bHFOMG1nV2lJQ0lpQUNJaUJEekZrTksrb0lGbEwzU2dFTUFsaVBBR1lFa0RPT214YVRDMms5eXFyVmEzclg5akh2dmZlZTlhOFRBUkVRZ2Nqck4wak5nWTJEUTV1R0tVbVNKRWtTRm9JSWlJQUlSTjBzZFBNdFc3ZU5qRzRuZU8rOTgyekhUaEVRQVJHSXVvdFVHdG05Wisramd5dFNDbVA3OWdzMlBOWXIyUEVEQndWYk1sL042UkJZY2ZoSVVhOXZvU1JKa2lSSm1EOHFJaEZoUkNCNmkyZGxNdkx1aVdONW5uWlVXSWpQWk5RcG5WWlZWUmJpTTFNVklHZlpiSlpsV2NhOEhFbzllMmlDVm9HT24zRDhjUmlDY0lDTUVTd21FSEgvRTNhL2g1L0RreWROR1RSeDVCU2Q1bE9zcTJWbVpzV0t5ZjVWR1owNUs1aHo4eEJNNlo0U2svUGlEb0wwOUlXTHpWcXQyV1NYWkpWUnF1eXBXV0dzbFhiUVpRNUtJTFRCTEhqQjJ1b1ZLMWlxU1lpK0dMV3Q1NW1RdExXMXNSQ1h0VmUzTW1QSzgxZWVIZDYyTFZDTzUyd1ZUT25hb1dLQ3FmZlhMN1BuZmFkbkc5bjZLL0sxNkRkdWRyZDB6N1BMOGR2QUhjdGVhQVlYMXRScHFYU3BERm5sVytLTDFkdDVuai9PMHRqZDRRWGZkN2VtcXJXVWdoRVJtMXRrcGZIblZGVTFwY0F0QndjSEIrczFtN0xsL2lyejNIQ0lweWxJaHl1VlNpVlVVZ3JjMGd0aytMTVhMVmsrUkdiSXpqMVIxY1BwYkVyRDVMMG45OUxMMzdsVVM3KzdGWnNOSFNPUTJiaVgrOVd2R0VPUDBxdjBQWnJoeXI0L0Y3Rm42dWIrYUsrY0Yzdm5UNTJiQjhnNTUzaXZzM1RtM2oxUENGT09yQ05yQUdaMndqdkR5eGVhemsyRDFzeThkcDYxMVdseUJpMTcwcTcrNURnbE83WjArQjdrWklRelJqSUVDWVRJOTQrZEY0enNNdHFiNTl0NEVwdUJ3ZGVGTnd5OUtaZ0llV3l5dmRlM2I3ek5FcnFSMW1yak5Kb25TWklrS1NXNUNFZ2dpRURVSDFUZU9pMFllZm1vSzRxaUtKaVhRdW5kRHhsNGd3eS9USG4rbzZJSVJjSFVrUk9TSmhubW1CbTJuanN5VmNGSS91TGJVcFVncmR0NG9Kcm4xU29Mc1Z1NVQzd3gza2xTVWxPNlhCeDQ0bzZRa1l0ZnQvZ1dacmxqcHZSSFpFUjRKNnFlZmJlMXRYWWpZeUUrUDQ1YTd2bUpxcllwQy9GcFJxM29lNnFxeWtKOGZpbytBSVMrRnFPcXFoUm9mUHA5d1g1QXloeFp1aXNoK3MvWXowYzRwTFpWRDdWVzY2cXhMSkt5Y3piUVRYNkpqSnpJTFZITDVWOVVLcFgyZ29XNEhEaEJrNllUaC9BaFJnblVnTVZ4d2dqa2hERGxUQlNIVHRBMGNwRHJ5aTFnTDE1bmRlRVVEVGNhalFaTDQvZVIyTlVWUWdnaG94Qy81MFZkVkZWVnBSQzdoOHdJMVVKVjFTZVVScmxrUCs1amp2b281WWE4K1lSYmFyQ1htQkgzbld1d3M2WUxxL0JMQXRsejVsY096RmlRdGF4bm5iTjgzdlJaS1Z4MGx2WFpzQ3c5bjFLRnZYMTZHYm5WN0ZQV2hPQVlPRGpBeHZPckUwNFlZZzlLczhUSG9yb29LdldVK3BWeDJuZUIyZklqd0FKLythT0RaUG0xa1g2eTdQVm5MZytRbzF0amRIdU9scEw1VHFvZW80RTFkUEEydDV2cEtPdnF1MHNqemZ1R2xqdnAxeE9mOGMyN1JqUEhVdml4OURIdmdWRmpRZWwyTzB4d1pITy9pNzFqRXZvODJncld0K0g2QTNLT3ZVZFBrK0hqdjJGK21EKzZrWWErRU03UTV6MTBUMWovVzdhZFRmTWwvaVVacEJ6MFByNkNBTHBvMk8vbzkvZ2FiQTV6WkV2ekI1WVgzUENDZ3dvSkJJQjJVOGEvemd4bDNGQmdnYVdJOUZBQk9QWk5sRDhtZjZKZWNtUXNLRkNhc0Q4WHJJTS94TmM4elNMK0JUQW9NMk9vQnNQQTJsSG1OcUdLWllYbkRaWjNnbXk1SkIyOHpEdUZnb0VHcEhaak5LTXFEVkdHTDhxc2hYOG1UTkpia2RmSUMvU05jT2JXKzhLYmlFMWJnMEFOQnFIQkdtUllnMEhvT0VuOXZLK1B0WE1iNFd5Sld1Vy8vazJxMDdzMEZmMWtTWjY4aFNrY1dLU3IyOEFQelU1WStqdlkwZWxuSFhPWURKWXMySWtQakRTamZ0YnhZWnJ3WkUrT01mK0FGajVrcmZQMTVndHJ1ZjlIRFpLcEdNUEJ1dzZ5RXkzazBtNDJ3UEtsU0t2bVFXdndPRUZLblpHeU45ZGE2VGxJYnM4T3l4cm92VU8ydzdGN0REdDNDUlhlaXhhQzVNOFlYZ0hkZGtacWdyZFFRWVkycE9SV1UzOGdSempPL0xkYkJXVlZxbTRtYTNqaG5xcTRRbGlDZ1ZCWlp5MDFhT3RKVzhOV3Z5STBmUUxlWUJYbmp2SVdZeVdJV2pQZlhpYVR3Y0U1NWo0c3ZQZGs0Y3ZldXdxb1JzNTU1N0ZBUG1XYjlzM1IrbGZ2Q3F2L3lVQlAwbkxMN0NMcnRNd0tBQzBLdTIvZ0dRRjB4VVE5UkJmNGtaWGw3cHlQMklhZEU3NDAxQ1lnUDBYSHhhOUswNnVEL0JOVHRZSWVOS3dYSFA2K1ladkhKcE9tWjRON2hwckpJR0c2QzJSUWNhTkhLM2txTExWYXNhMnNXd3dWUjd6MUh1VEp1ZmFQWjVjbGREUEp2Q1huREp5M2NEdlI1NDFROTFhWHQxTXJ2WFJNdWovNFdwZGJtT2luOVpIWFF6U0lua1cvZjFMY0djTlBvMWJjdjhybGNybGdJVDcvbG85S1dXWlZWWldGK055SnFscFhWVlVXNHBQSnQ2UXNzNnFxeWtKOC9oTlY5VXRWVldVaFB2K05xcXFxcXNwQ2ZQNFhWYld1cXFvc3hPZWpxS3FmcTZvcUMvRmJTT2l3Y0UxOEE0Z3Q0dXZreFVYcE1mcC8
|
|||
|
<link href="data:text/css; charset=UTF-8;base64,LyogUHJpc21KUyAxLjI5LjAKaHR0cHM6Ly9wcmlzbWpzLmNvbS9kb3dubG9hZC5odG1sI3RoZW1lcz1wcmlzbS1va2FpZGlhJmxhbmd1YWdlcz1tYXJrdXArY3NzK2NsaWtlK2phdmFzY3JpcHQrYXJkdWlubytiYXNoK2MrY3NoYXJwK2NwcCtjc3MtZXh0cmFzK2Nzditkb2NrZXIrZXhjZWwtZm9ybXVsYStnaXQramF2YStqYXZhZG9jK2phdmFkb2NsaWtlK2phdmFzdGFja3RyYWNlK2pzb24ranNvbjUrbG9nK21hcmtkb3duK25naW54K25peCtweXRob24rcnVzdCt2aW0rd2lraSZwbHVnaW5zPWxpbmUtbnVtYmVycyt0b29sYmFyK2NvcHktdG8tY2xpcGJvYXJkICovCmNvZGVbY2xhc3MqPWxhbmd1YWdlLV0sCnByZVtjbGFzcyo9bGFuZ3VhZ2UtXSB7CiAgICBjb2xvcjogI2Y4ZjhmMjsKICAgIGJhY2tncm91bmQ6ICMwZTBmMGY7CiAgICB0ZXh0LXNoYWRvdzogMCAxcHggcmdiYSgwLCAwLCAwLCAuMyk7CiAgICBmb250LWZhbWlseTogJ0ZpcmFDb2RlJywgdXJsKCdkYXRhOmZvbnQvd29mZjI7YmFzZTY0LGQwOUdNZ0FCQUFBQURtNmtBQklBQUFBZ3h4UUFEbTR6QUFZQWd3QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHb05ZRzRHUlFCeUMrV0lHWUQ5UVprVmtoRGdBeURnSWdTZ0puQlVSQ0Fydm9YVGE5ZzBCTmdJa0E0R3ZaZ3VDMzBBQUJDQUZrRnNIaXMwR0RJRldteklBRzEzQmcrSFB2WGVBNGo1bDY4d1FxaE0wSTF1Q3licVkyU3NVbWw3UmZ6N0pwcWFIbFB5TVFxRjNyWitlZkhpV1BOUEhKM3p4SmoxUVlsSzNPdnN4SWdlZ3FpcnVoK2NUU0l6dDlvRkxZTVlqcW1wV2ZZM3d0Z0dsejRNaHN2Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9kOHArbjNzMTc3L3p4dkdYbTNabjVXN1lmQ0NGQVNJQWZFc0tTc0Jzd3JDRWJhR1NOeUJJaUNvSkJRRnR0RWJXMmFtdlJscnEwVm11MXRiYTczUW1HclBOSjR0T2dXUjdTd3BiSlZpajNlWlpXMHpSTkxmbWE4L0F1cTdlMHBtbVJ0cldqSTJua3FIWVlxaVdkeTRUbE51bHFOMG1nV2lJQ0lpQUNJaUJEekZrTksrb0lGbEwzU2dFTUFsaVBBR1lFa0RPT214YVRDMms5eXFyVmEzclg5akh2dmZlZTlhOFRBUkVRZ2Nqck4wak5nWTJEUTV1R0tVbVNKRWtTRm9JSWlJQUlSTjBzZFBNdFc3ZU5qRzRuZU8rOTgyekhUaEVRQVJHSXVvdFVHdG05Wisramd5dFNDbVA3OWdzMlBOWXIyUEVEQndWYk1sL042UkJZY2ZoSVVhOXZvU1JKa2lSSm1EOHFJaEZoUkNCNmkyZGxNdkx1aVdONW5uWlVXSWpQWk5RcG5WWlZWUmJpTTFNVklHZlpiSlpsV2NhOEhFbzllMmlDVm9HT24zRDhjUmlDY0lDTUVTd21FSEgvRTNhL2g1L0RreWROR1RSeDVCU2Q1bE9zcTJWbVpzV0t5ZjVWR1owNUs1aHo4eEJNNlo0U2svUGlEb0wwOUlXTHpWcXQyV1NYWkpWUnF1eXBXV0dzbFhiUVpRNUtJTFRCTEhqQjJ1b1ZLMWlxU1lpK0dMV3Q1NW1RdExXMXNSQ1h0VmUzTW1QSzgxZWVIZDYyTFZDTzUyd1ZUT25hb1dLQ3FmZlhMN1BuZmFkbkc5bjZLL0sxNkRkdWRyZDB6N1BMOGR2QUhjdGVhQVlYMXRScHFYU3BERm5sVytLTDFkdDVuai9PMHRqZDRRWGZkN2VtcXJXVWdoRVJtMXRrcGZIblZGVTFwY0F0QndjSEIrczFtN0xsL2lyejNIQ0lweWxJaHl1VlNpVlVVZ3JjMGd0aytMTVhMVmsrUkdiSXpqMVIxY1BwYkVyRDVMMG45OUxMMzdsVVM3KzdGWnNOSFNPUTJiaVgrOVd2R0VPUDBxdjBQWnJoeXI0L0Y3Rm42dWIrYUsrY0Yzdm5UNTJiQjhnNTUzaXZzM1RtM2oxUENGT09yQ05yQUdaMndqdkR5eGVhemsyRDFzeThkcDYxMVdseUJpMTcwcTcrNURnbE83WjArQjdrWklRelJqSUVDWVRJOTQrZEY0enNNdHFiNTl0NEVwdUJ3ZGVGTnd5OUtaZ0llV3l5dmRlM2I3ek5FcnFSMW1yak5Kb25TWklrS1NXNUNFZ2dpRURVSDFUZU9pMFllZm1vSzRxaUtKaVhRdW5kRHhsNGd3eS9USG4rbzZJSVJjSFVrUk9TSmhubW1CbTJuanN5VmNGSS91TGJVcFVncmR0NG9Kcm4xU29Mc1Z1NVQzd3gza2xTVWxPNlhCeDQ0bzZRa1l0ZnQvZ1dacmxqcHZSSFpFUjRKNnFlZmJlMXRYWWpZeUUrUDQ1YTd2bUpxcllwQy9GcFJxM29lNnFxeWtKOGZpbytBSVMrRnFPcXFoUm9mUHA5d1g1QXloeFp1aXNoK3MvWXowYzRwTFpWRDdWVzY2cXhMSkt5Y3piUVRYNkpqSnpJTFZITDVWOVVLcFgyZ29XNEhEaEJrNllUaC9BaFJnblVnTVZ4d2dqa2hERGxUQlNIVHRBMGNwRHJ5aTFnTDE1bmRlRVVEVGNhalFaTDQvZVIyTlVWUWdnaG94Qy81MFZkVkZWVnBSQzdoOHdJMVVKVjFTZVVScmxrUCs1amp2b281WWE4K1lSYmFyQ1htQkgzbld1d3M2WUxxL0JMQXRsejVsY096RmlRdGF4bm5iTjgzdlJaS1Z4MGx2WFpzQ3c5bjFLRnZYMTZHYm5WN0ZQV2hPQVlPRGpBeHZPckUwNFlZZzlLczhUSG9yb29LdldVK3BWeDJuZUIyZklqd0FKLythT0RaUG0xa1g2eTdQVm5MZytRbzF0amRIdU9scEw1VHFvZW80RTFkUEEydDV2cEtPdnF1MHNqemZ1R2xqdnAxeE9mOGMyN1JqUEhVdml4OURIdmdWRmpRZWwyTzB4d1pITy9pNzFqRXZvODJncld0K0g2QTNLT3ZVZFBrK0hqdjJGK21EKzZrWWErRU03UTV6MTBUMWovVzdhZFRmTWwvaVVacEJ6MFByNkNBTHBvMk8vbzkvZ2FiQTV6WkV2ekI1WVgzUENDZ3dvSkJJQjJVOGEvemd4bDNGQmdnYVdJOUZBQk9QWk5sRDhtZjZKZWNtUXNLRkNhc0Q4WHJJTS94TmM4elNMK0JUQW9NMk9vQnNQQTJsSG1OcUdLWllYbkRaWjNnbXk1SkIyOHpEdUZnb0VHcEhaak5LTXFEVkdHTDhxc2hYOG1UTkpia2RmSUMvU05jT2JXKzhLYmlFMWJnMEFOQnFIQkdtUllnMEhvT0VuOXZLK1B0WE1iNFd5Sld1Vy8vazJxMDdzMEZmMWtTWjY4aFNrY1dLU3IyOEFQelU1WStqdlkwZWxuSFhPWURKWXMySWtQakRTamZ0YnhZWnJ3WkUrT01mK0FGajVrcmZQMTVndHJ1ZjlIRFpLcEdNUEJ1dzZ5RXkzazBtNDJ3UEtsU0t2bVFXdndPRUZLblpHeU45ZGE2VGxJYnM4T3l4cm92VU8ydzdGN0REdDNDUlhlaXhhQzVNOFlYZ0hkZGtacWdyZFFRWVkycE9SV1UzOGdSempPL0xkYkJXVlZxbTRtYTNqaG5xcTRRbGlDZ1ZCWlp5MDFhT3RKVzhOV3Z5STBmUUxlWUJYbmp2SVdZeVdJV2pQZlhpYVR3Y0U1NWo0c3ZQZGs0Y3ZldXdxb1JzNTU1N0ZBUG1XYjlzM1IrbGZ2Q3F2L3lVQlAwbkxMN0NMcnRNd0tBQzB
|
|||
|
</head>
|
|||
|
<body class="line-numbers">
|
|||
|
<h1 id="this-page-is-portable">This page is portable</h1>
|
|||
|
<p>This page, even with its images, fonts, and javascript, is
|
|||
|
completely portable, and will work offline with no other
|
|||
|
files.</p>
|
|||
|
<hr/>
|
|||
|
<p>This is essentially a showcase and writeup about <a href="https://git.askiiart.net/askiiart/one-webpage-under-god">One
|
|||
|
Webpage, Under God</a>, a program I made to make a page
|
|||
|
completely portable and independent of any other files. It
|
|||
|
doesn't handle everything, but does perfectly on a simple static
|
|||
|
site like my own, with images, fonts, and javascript, it works
|
|||
|
perfectly.</p>
|
|||
|
<div class="sourceCode" id="cb1"><pre class="language-rs"><code class="language-rust"><span id="cb1-1"><a aria-hidden="true" href="#cb1-1" tabindex="-1"></a><span class="kw">let</span> hello <span class="op">=</span> <span class="st">"hiiiiiiiiii"</span><span class="op">;</span></span>
|
|||
|
<span id="cb1-2"><a aria-hidden="true" href="#cb1-2" tabindex="-1"></a><span class="co">// Check out this fancy code block without using any other files</span></span></code></pre></div>
|
|||
|
<figure>
|
|||
|
<img alt="I can even have this picture of a turtle in here" src="data:image/avif;base64,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
|
|||
|
<figcaption aria-hidden="true">I can even have this picture of a
|
|||
|
turtle in here</figcaption>
|
|||
|
</figure>
|
|||
|
<h2 id="okay-but-how">Okay but how</h2>
|
|||
|
<p>Really, this page should be titled "All hail the <a href="https://en.wikipedia.org/wiki/Data_URI_scheme">Data URI
|
|||
|
Scheme</a> and whoever came up with it, that's how this entire
|
|||
|
program works. If you're unaware, a data URI looks like
|
|||
|
this:</p>
|
|||
|
<div class="sourceCode" id="cb2"><pre class="language-txt"><code class="language-default"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1" tabindex="-1"></a>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA</span></code></pre></div>
|
|||
|
<p>To break this down:</p>
|
|||
|
<ul>
|
|||
|
<li><code>data:</code> This is a data URI</li>
|
|||
|
<li><code>image/png</code>: The <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types">MIME
|
|||
|
type</a> of the data</li>
|
|||
|
<li><code>;base64</code> Indicates that this is encoded in
|
|||
|
base64 (optional, see <a href="https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data">MDN
|
|||
|
docs</a>)</li>
|
|||
|
<li><code>iVBORw0KGgoAAAANSUhEUgAAAA</code>: base64-encoded
|
|||
|
data</li>
|
|||
|
</ul>
|
|||
|
<p>If it's text data, then it can use percent-encoding instead,
|
|||
|
though I couldn't get this to work, so I just encoded everything
|
|||
|
in base64 instead.</p>
|
|||
|
<h2 id="fonts">Fonts</h2>
|
|||
|
<p>The rest of all this is really simple - we just replace the
|
|||
|
link to the asset with a data URI. Fonts, however, are more
|
|||
|
complicated. They're linked in the CSS, not the HTML, which
|
|||
|
leads to <em>this</em> mess - fonts encoded in base64, inside of
|
|||
|
CSS which is then itself encoded in base64.</p>
|
|||
|
<div class="sourceCode" id="cb3"><pre class="language-css"><code class="language-css"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1" tabindex="-1"></a><span class="im">@font-face</span> {</span>
|
|||
|
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2" tabindex="-1"></a> <span class="co">/* from https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode */</span></span>
|
|||
|
<span id="cb3-3"><a aria-hidden="true" href="#cb3-3" tabindex="-1"></a> <span class="kw">font-family</span><span class="ch">:</span> <span class="st">"FiraCode"</span><span class="op">;</span></span>
|
|||
|
<span id="cb3-4"><a aria-hidden="true" href="#cb3-4" tabindex="-1"></a> <span class="kw">src</span><span class="ch">:</span> <span class="st">'FiraCode'</span><span class="op">,</span> <span class="fu">url(</span><span class="st">'data:font/woff2;base64,d09GMgABAA...76Ufr9TLXi4DgAA'</span><span class="fu">)</span><span class="op">;</span></span>
|
|||
|
<span id="cb3-5"><a aria-hidden="true" href="#cb3-5" tabindex="-1"></a>}</span></code></pre></div>
|
|||
|
<p>This also led to me being reminded how huge my fonts are;
|
|||
|
because of them my site's homepage comes out to nearly 2 MiB
|
|||
|
even without <code>prism.js</code>, which contains a duplicate
|
|||
|
FiraCode Nerd Font, which is of course also hardcoded in.</p>
|
|||
|
<hr/>
|
|||
|
<p>One last thing: Relative links are very <em>not</em> portable
|
|||
|
of course, so I just tacked on this bit to the end to fix
|
|||
|
that</p>
|
|||
|
<div class="sourceCode" id="cb4"><pre class="language-py"><code class="language-python"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1" tabindex="-1"></a>links <span class="op">=</span> soup.find_all(<span class="st">'link'</span>)</span>
|
|||
|
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2" tabindex="-1"></a><span class="cf">for</span> item <span class="kw">in</span> links:</span>
|
|||
|
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3" tabindex="-1"></a> <span class="cf">if</span> <span class="st">'stylesheet'</span> <span class="kw">not</span> <span class="kw">in</span> item.attrs[<span class="st">'rel'</span>] <span class="kw">and</span> <span class="st">'icon'</span> <span class="kw">not</span> <span class="kw">in</span> item.attrs[<span class="st">'rel'</span>]:</span>
|
|||
|
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4" tabindex="-1"></a> item.attrs[<span class="st">'href'</span>] <span class="op">=</span> absolute_url(item.attrs[<span class="st">'href'</span>], domain_thing)</span></code></pre></div>
|
|||
|
<p>Oh also, this page is actually <em>not</em> portable - aside
|
|||
|
from the johnvertisement iframe at the bottom, I didn't make it
|
|||
|
portable regardless because it's 3+ MiB, and I didn't want to
|
|||
|
put that kind of load on my internet connection for no reason.
|
|||
|
If it weren't for my upload speed suddenly sexdecupling (16x)
|
|||
|
for some reason, it would take more than a second to load. The
|
|||
|
<em>actually portable</em> version is <a href="/blog/this-page-is-actually-portable.html">here</a></p>
|
|||
|
<iframe src="https://john.citrons.xyz/embed?ref=askiiart.net" style="margin-left:auto;display:block;margin-right:auto;max-width:732px;width:100%;height:94px;border:none;"></iframe>
|
|||
|
<script src="/prism.js"></script>
|
|||
|
|
|||
|
<footer>
|
|||
|
<p><a href="https://git.askiiart.net/askiiart/askiiart-net">code</a> (<a href="https://github.com/askiiart/askiiart.github.io">mirror</a>) <a href="/feed.xml">rss</a> <a href="/pubkey.asc">pubkey</a></p>
|
|||
|
</footer>
|
|||
|
|
|||
|
</body></html>
|