Repos / s4g / d80933e439
commit d80933e439c35b58a74ea77c452793abeb6abd2a
Author: Nhân <hi@imnhan.com>
Date:   Thu Aug 31 19:30:34 2023 +0700

    header autolink

diff --git a/Makefile b/Makefile
index d9bbd9c..95570dc 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ build:
 
 watch:
 	fd -E docs -E theme | entr -rc -s \
-		'go build -o dist/ && ./dist/s4g serve -f docs -p 8000'
+		'go build -o dist/ && ./dist/s4g serve -f docs -p 3338'
 
 watch-theme:
 	find theme/* | entr -c rsync -av theme/ docs/_s4g/theme/
diff --git a/djot/js/main.js b/djot/js/main.js
index 2d84655..bd4d4df 100644
--- a/djot/js/main.js
+++ b/djot/js/main.js
@@ -31,7 +31,22 @@ function concatTypedArray(former, latter) {
 
 function handleMessage(msg) {
   const input = new TextDecoder().decode(msg);
-  const output = djot.renderHTML(djot.parse(input));
+  const ast = djot.parse(input);
+  djot.applyFilter(ast, createHeadingLinks);
+  const output = djot.renderHTML(ast);
   const outputBytes = new TextEncoder().encode(output);
   process.stdout.write(concatTypedArray(outputBytes, END));
 }
+
+function createHeadingLinks() {
+  return {
+    section: (e) => {
+      e.children[0].children.push({
+        tag: "link",
+        destination: "#" + e.attributes.id,
+        children: [{ tag: "str", text: "#" }],
+        attributes: { class: "heading-link" },
+      });
+    },
+  };
+}
diff --git a/docs/_s4g/theme/base.css b/docs/_s4g/theme/base.css
index c5cb7f3..db89b40 100644
--- a/docs/_s4g/theme/base.css
+++ b/docs/_s4g/theme/base.css
@@ -18,6 +18,24 @@ a[target="_blank"]::after {
   content: "↗";
 }
 
+a.heading-link {
+  text-decoration: none;
+  margin-left: 0.3em;
+  visibility: hidden;
+}
+:hover > a.heading-link {
+  visibility: visible;
+}
+section:target > h2,
+section:target > h3,
+section:target > h4,
+section:target > h5,
+section:target > h6 {
+  background-color: #beefff;
+  margin-left: -1rem;
+  padding-left: 1rem;
+}
+
 main img,
 main video {
   max-width: 100%;
diff --git a/docs/about/index.html b/docs/about/index.html
index 691703d..3620deb 100644
--- a/docs/about/index.html
+++ b/docs/about/index.html
@@ -35,14 +35,14 @@ <h1>About</h1>
 <p>The articles themselves are just, uh, <em>colorful</em> lorem ipsums.
 Don’t worry too much about their actual content.</p>
 <section id="Sales-pitch">
-<h2>Sales pitch</h2>
+<h2>Sales pitch<a href="#Sales-pitch" class="heading-link">#</a></h2>
 <p>s4g aims to assist, not obscure. All it does is reading <code>.dj</code> files and
 spitting out <code>.html</code>s, leaving unrelated files alone. This means the user is
 free to structure their web directory however they want, and relative links
 work out of the box.</p>
 </section>
 <section id="Features">
-<h2>Features</h2>
+<h2>Features<a href="#Features" class="heading-link">#</a></h2>
 <p>So far we have:</p>
 <ul>
 <li>
diff --git a/docs/mfws.html b/docs/mfws.html
index b85bf6a..bb9a840 100644
--- a/docs/mfws.html
+++ b/docs/mfws.html
@@ -37,7 +37,7 @@ <h1>This is a motherfucking website.</h1>
 
 <p>And it’s fucking perfect.</p>
 <section id="Seriously-what-the-fuck-else-do-you-want">
-<h2>Seriously, what the fuck else do you want?</h2>
+<h2>Seriously, what the fuck else do you want?<a href="#Seriously-what-the-fuck-else-do-you-want" class="heading-link">#</a></h2>
 <p>You probably build websites and think your shit is special. You think your 13
 megabyte parallax-ative home page is going to get you some fucking Awwward
 banner you can glue to the top corner of your site. You think your 40-pound
@@ -62,7 +62,7 @@ <h2>Seriously, what the fuck else do you want?</h2>
 </li>
 </ul>
 <section id="Well-guess-what-motherfucker">
-<h3>Well guess what, motherfucker:</h3>
+<h3>Well guess what, motherfucker:<a href="#Well-guess-what-motherfucker" class="heading-link">#</a></h3>
 <p>You. Are. Over-designing. Look at this shit. It’s a motherfucking website. Why
 the fuck do you need to animate a fucking trendy-ass banner flag when I hover
 over that useless piece of shit? You spent hours on it and added 80 kilobytes
@@ -73,7 +73,7 @@ <h3>Well guess what, motherfucker:</h3>
 </section>
 </section>
 <section id="It-s-fucking-lightweight">
-<h2>It’s fucking lightweight</h2>
+<h2>It’s fucking lightweight<a href="#It-s-fucking-lightweight" class="heading-link">#</a></h2>
 <p>This entire page weighs less than the gradient-meshed facebook logo on your
 fucking Wordpress site. Did you seriously load 100kb of jQuery UI just so you
 could animate the fucking background color of a div? You loaded all 7 fontfaces
@@ -81,14 +81,14 @@ <h2>It’s fucking lightweight</h2>
 beginning of your site? You piece of shit.</p>
 </section>
 <section id="It-s-responsive">
-<h2>It’s responsive</h2>
+<h2>It’s responsive<a href="#It-s-responsive" class="heading-link">#</a></h2>
 <p>You dumbass. You thought you needed media queries to be responsive, but no.
 Responsive means that it responds to whatever motherfucking screensize it’s
 viewed on. This site doesn’t care if you’re on an iMac or a motherfucking
 Tamagotchi.</p>
 </section>
 <section id="It-fucking-works">
-<h2>It fucking works</h2>
+<h2>It fucking works<a href="#It-fucking-works" class="heading-link">#</a></h2>
 <p>Look at this shit. You can read it … that is, if you can read, motherfucker.
 It makes sense. It has motherfucking hierarchy. It’s using HTML5 tags so you
 and your bitch-ass browser know what the fuck’s in this fucking site. That’s
@@ -99,14 +99,14 @@ <h2>It fucking works</h2>
 <p>Cross-browser compatibility? Load this motherfucker in IE6. I fucking dare you.</p>
 </section>
 <section id="This-is-a-website-Look-at-it-You-ve-never-seen-one-before">
-<h2>This is a website. Look at it. You’ve never seen one before.</h2>
+<h2>This is a website. Look at it. You’ve never seen one before.<a href="#This-is-a-website-Look-at-it-You-ve-never-seen-one-before" class="heading-link">#</a></h2>
 <p>Like the man who’s never grown out his beard has no idea what his true natural
 state is, you have no fucking idea what a website is. All you have ever seen
 are shitty skeuomorphic bastardizations of what should be text communicating a
 fucking message. This is a real, naked website. Look at it. It’s fucking
 beautiful.</p>
 <section id="Yes-this-is-fucking-satire-you-fuck">
-<h3>Yes, this is fucking satire, you fuck</h3>
+<h3>Yes, this is fucking satire, you fuck<a href="#Yes-this-is-fucking-satire-you-fuck" class="heading-link">#</a></h3>
 <p>I’m not actually saying your shitty site should look like this. What I’m saying
 is that all the problems we have with websites are <strong>ones we create ourselves</strong>.
 Websites aren’t broken by default, they are functional, high-performing, and
@@ -119,7 +119,7 @@ <h3>Yes, this is fucking satire, you fuck</h3>
 </section>
 </section>
 <section id="Epilogue">
-<h2>Epilogue</h2>
+<h2>Epilogue<a href="#Epilogue" class="heading-link">#</a></h2>
 <p>From the philosophies expressed (poorly) above, <a href="http://txti.es/">txti</a> was
 created. You should try it today to make your own motherfucking websites.</p>
 <hr>
diff --git a/docs/scale/index.html b/docs/scale/index.html
index b0e33c7..3be053f 100644
--- a/docs/scale/index.html
+++ b/docs/scale/index.html
@@ -43,7 +43,7 @@ <h1>I&#39;m Going To Scale My Foot Up Your Ass</h1>
 our blog.  Once that post hits Reddit, son, everyone will know how hardcore you
 really are.  Respect.</p>
 <section id="People-Who-Talk-Big-About-Scalability-Don-t-Need-To-Worry-About-It">
-<h2>People Who Talk Big About Scalability Don’t Need To Worry About It</h2>
+<h2>People Who Talk Big About Scalability Don’t Need To Worry About It<a href="#People-Who-Talk-Big-About-Scalability-Don-t-Need-To-Worry-About-It" class="heading-link">#</a></h2>
 <p>Fact:  every chest-thumping blog post I have seen written about scalability is
 either about architecture, Memcached, or both.  Some asshole who writes shitty
 code starts pontificating about <em>“scalable architecture”</em> with data storage,
@@ -56,7 +56,7 @@ <h2>People Who Talk Big About Scalability Don’t Need To Worry About It</h2>
 welcome to the modern age.  Hope you know what a cache expiry policy is.</p>
 </section>
 <section id="If-You-Haven-t-Discussed-Capacity-Planning-You-Can-t-Discuss-Scalability">
-<h2>If You Haven’t Discussed Capacity Planning, You Can’t Discuss Scalability</h2>
+<h2>If You Haven’t Discussed Capacity Planning, You Can’t Discuss Scalability<a href="#If-You-Haven-t-Discussed-Capacity-Planning-You-Can-t-Discuss-Scalability" class="heading-link">#</a></h2>
 <p>You don’t need to worry about scalability on your Rails-over-Mysql application
 because nobody is going to use it.  Really.  Believe me.  You’re going to get,
 at most, 1,000 people on your app, and maybe 1% of them will be 7-day active.
@@ -75,7 +75,7 @@ <h2>If You Haven’t Discussed Capacity Planning, You Can’t Discuss Scalabilit
 Amazon datacenters”.</p>
 </section>
 <section id="Choosing-Technology-Don-t-Mean-Shit-If-You-Don-t-Know-How-To-Use-It">
-<h2>Choosing Technology Don’t Mean Shit If You Don’t Know How To Use It</h2>
+<h2>Choosing Technology Don’t Mean Shit If You Don’t Know How To Use It<a href="#Choosing-Technology-Don-t-Mean-Shit-If-You-Don-t-Know-How-To-Use-It" class="heading-link">#</a></h2>
 <p>The most common butthurt about scalability is this:  choose a technology.  If
 you like the technology, claim <em>“technology X scales better!”</em> If you don’t
 like it, claim <em>“technology X doesn’t scale!”</em></p>
@@ -88,7 +88,7 @@ <h2>Choosing Technology Don’t Mean Shit If You Don’t Know How To Use It</h2>
 chances are, you’re doing it wrong.</p>
 </section>
 <section id="tl-dr">
-<h2>tl;dr</h2>
+<h2>tl;dr<a href="#tl-dr" class="heading-link">#</a></h2>
 <p>Shut up about scalability, no one is using your app anyway.</p>
 <style>
 img[alt="scaleboner"] { float: right; }
diff --git a/theme/base.css b/theme/base.css
index c5cb7f3..db89b40 100644
--- a/theme/base.css
+++ b/theme/base.css
@@ -18,6 +18,24 @@ a[target="_blank"]::after {
   content: "↗";
 }
 
+a.heading-link {
+  text-decoration: none;
+  margin-left: 0.3em;
+  visibility: hidden;
+}
+:hover > a.heading-link {
+  visibility: visible;
+}
+section:target > h2,
+section:target > h3,
+section:target > h4,
+section:target > h5,
+section:target > h6 {
+  background-color: #beefff;
+  margin-left: -1rem;
+  padding-left: 1rem;
+}
+
 main img,
 main video {
   max-width: 100%;