Skip to content

Commit 3a298c1

Browse files
add linkers every where;
1 parent fe8989b commit 3a298c1

8 files changed

Lines changed: 236 additions & 25 deletions

File tree

POST_GUIDE.md

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ Use the `tikz` shortcode:
7777
The diagram renders in the browser via TikZJax - no build step needed.
7878
Use TikZ's own `scale` option to resize diagrams, e.g. `\begin{tikzpicture}[scale=0.5]`.
7979

80+
Optional parameters:
81+
82+
| Parameter | Example | Notes |
83+
| --------- | ------------------------- | ------------------------------------------------------------- |
84+
| `caption` | `caption="Step diagram."` | Caption shown below the diagram |
85+
| `id` | `id="fig-walk"` | Anchor id; auto-generated as `fig-1`, `fig-2`, ... if omitted |
86+
8087
### Images
8188

8289
Place images in the `static/images` folder, then reference them with an
@@ -88,33 +95,91 @@ absolute path:
8895

8996
To control the size, use the `img` shortcode instead:
9097

98+
```markdown
99+
{{< img src="/images/my-diagram.png" caption="A random walk after 1000 steps." width="50" >}}
91100
```
92-
{{< img src="/images/my-diagram.png" alt="Alt text" width="50" >}}
101+
102+
| Parameter | Example | Notes |
103+
| --------- | -------------------------- | ------------------------------------------------------------- |
104+
| `src` | `src="/images/x.png"` | Path to the image (required) |
105+
| `caption` | `caption="A random walk."` | Caption shown below; also used as alt text |
106+
| `width` | `width="50"` | Max width as % of container; default 100% |
107+
| `id` | `id="fig-walk"` | Anchor id; auto-generated as `fig-1`, `fig-2`, ... if omitted |
108+
109+
### Tables
110+
111+
For plain tables with no caption or cross-reference, use standard Markdown syntax:
112+
113+
```markdown
114+
| Column A | Column B |
115+
| -------- | -------- |
116+
| value | value |
93117
```
94118

95-
| Parameter | Example | Notes |
96-
| --------- | --------------------- | ----------------------------------------- |
97-
| `src` | `src="/images/x.png"` | Path to the image (required) |
98-
| `alt` | `alt="A diagram"` | Alt text for accessibility |
99-
| `width` | `width="50"` | Max width as % of container; default 100% |
119+
To add a caption or a linkable anchor, wrap the table in the `table` shortcode:
120+
121+
```markdown
122+
{{< table id="tbl-transitions" caption="The four possible transitions from $f_m(k)$." >}}
123+
| Direction | Probability |
124+
| ----------- | ----------- |
125+
| $(+1,+1)$ | $1/4$ |
126+
| $(+1,-1)$ | $1/4$ |
127+
| $(-1,+1)$ | $1/4$ |
128+
| $(-1,-1)$ | $1/4$ |
129+
{{< /table >}}
130+
```
131+
132+
| Parameter | Example | Notes |
133+
| --------- | ----------------------------- | ------------------------------------------------------------- |
134+
| `caption` | `caption="Transition table."` | Caption shown below the table |
135+
| `id` | `id="tbl-transitions"` | Anchor id; auto-generated as `tbl-1`, `tbl-2`, ... if omitted |
136+
137+
### Cross-referencing
138+
139+
Both the `img` and `tikz` shortcodes accept an optional `id` parameter that
140+
places an HTML `id` on the figure wrapper, making it a linkable anchor.
141+
142+
```markdown
143+
{{< img src="/images/random-walk.png" id="fig-walk" >}}
144+
{{< tikz id="fig-diagram" >}}...{{< /tikz >}}
145+
```
146+
147+
**Same page** plain hash link:
148+
149+
```markdown
150+
[see Figure](#fig-walk)
151+
```
152+
153+
**Cross-post** use Hugo's `relref` shortcode:
154+
155+
```markdown
156+
[see Figure]({{< relref "other-post.md#fig-walk" >}})
157+
```
158+
159+
Keep ids short and descriptive. Prefix with `fig-` by convention to avoid
160+
conflicts with heading anchors.
161+
162+
---
100163

101164
### Videos
102165

103166
Place videos in `static/videos/` and use the `videos` shortcode:
104167

105-
```
168+
```markdown
106169
{{< video src="/videos/my-clip.mp4" >}}
107170
```
108171

109172
Optional parameters:
110173

111-
| Parameter | Example | Notes |
112-
| --------- | ------------------------ | ----------------------------------------- |
113-
| `src` | `src="/videos/clip.mp4"` | Path to the video (required) |
114-
| `width` | `width="50"` | Max width as % of container; default 100% |
115-
| `type` | `type="video/webm"` | MIME type; defaults to `video/mp4` |
174+
| Parameter | Example | Notes |
175+
| --------- | ------------------------ | ------------------------------------------------------------- |
176+
| `src` | `src="/videos/clip.mp4"` | Path to the video (required) |
177+
| `caption` | `caption="Simulation."` | Caption shown below the video |
178+
| `width` | `width="50"` | Max width as % of container; default 100% |
179+
| `type` | `type="video/webm"` | MIME type; defaults to `video/mp4` |
180+
| `id` | `id="fig-walk"` | Anchor id; auto-generated as `fig-1`, `fig-2`, ... if omitted |
116181

117-
```
182+
```markdown
118183
{{< video src="/videos/my-clip.webm" type="video/webm" width="50" >}}
119184
```
120185

themes/math-gallery-theme/assets/css/main.css

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,11 @@ a.page-btn:hover {
592592
margin: 1rem 0;
593593
}
594594

595+
.table-wrap .post-content table,
596+
.table-wrap table {
597+
margin: 0;
598+
}
599+
595600
.post-content th,
596601
.post-content td {
597602
border: 1px solid var(--border);
@@ -626,6 +631,77 @@ li code {
626631
padding: 0.1em 0.35em;
627632
}
628633

634+
/* ============================================================
635+
Anchor links (headings + figures)
636+
============================================================ */
637+
638+
.post-content h2,
639+
.post-content h3,
640+
.post-content h4,
641+
.post-content h5,
642+
.post-content h6 {
643+
position: relative;
644+
}
645+
646+
.heading-anchor {
647+
opacity: 0;
648+
margin-left: 0.35em;
649+
color: var(--text-muted);
650+
text-decoration: none;
651+
vertical-align: middle;
652+
transition:
653+
opacity var(--transition),
654+
color var(--transition);
655+
}
656+
657+
.post-content h2:hover .heading-anchor,
658+
.post-content h3:hover .heading-anchor,
659+
.post-content h4:hover .heading-anchor,
660+
.post-content h5:hover .heading-anchor,
661+
.post-content h6:hover .heading-anchor {
662+
opacity: 1;
663+
}
664+
665+
.heading-anchor:hover {
666+
color: var(--accent);
667+
}
668+
669+
/* Figure anchor - bottom-right corner, shown on hover */
670+
.media-figure,
671+
.tikz-wrap,
672+
.table-wrap {
673+
position: relative;
674+
}
675+
676+
.fig-anchor {
677+
position: absolute;
678+
bottom: 0.4rem;
679+
right: 0.5rem;
680+
opacity: 0;
681+
color: var(--text-muted);
682+
text-decoration: none;
683+
line-height: 1;
684+
transition:
685+
opacity var(--transition),
686+
color var(--transition);
687+
}
688+
689+
/* Tables: anchor sits top-right so it's always visible on long tables */
690+
.fig-anchor--top {
691+
bottom: auto;
692+
top: 0.4rem;
693+
}
694+
695+
.media-figure:hover .fig-anchor,
696+
.tikz-wrap:hover .fig-anchor,
697+
.table-wrap:hover .fig-anchor {
698+
opacity: 1;
699+
}
700+
701+
.fig-anchor:hover {
702+
color: var(--accent);
703+
}
704+
629705
/* ============================================================
630706
Media figures (img / video shortcodes)
631707
============================================================ */
@@ -655,6 +731,15 @@ li code {
655731
width: 100%;
656732
}
657733

734+
/* Captions */
735+
figcaption {
736+
margin-top: 0.4rem;
737+
text-align: center;
738+
font-size: 0.8rem;
739+
color: var(--text-muted);
740+
font-style: italic;
741+
}
742+
658743
/* ============================================================
659744
TikZ SVG
660745
============================================================ */
@@ -771,7 +856,7 @@ script[type="text/tikz"] + svg,
771856
font-size: 1rem;
772857
}
773858

774-
/* Footer: 2 rows (nav + social) then copyright */
859+
/* Footer: 2 rows - (nav + social) then copyright */
775860
.footer-links {
776861
flex-direction: row;
777862
flex-wrap: wrap;

themes/math-gallery-theme/assets/css/syntax.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
}
3636

3737
/* ============================================================
38-
Dark theme Gruvbox
38+
Dark theme - Gruvbox
3939
============================================================ */
4040

4141
:root:not([data-theme="light"]) .bg {
@@ -235,7 +235,7 @@
235235
}
236236

237237
/* ============================================================
238-
Light theme Solarized Light
238+
Light theme - Solarized Light
239239
============================================================ */
240240

241241
[data-theme="light"] .bg {

themes/math-gallery-theme/assets/js/main.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,57 @@
6161
if (e.target.tagName === "A") closeNav();
6262
});
6363
}
64+
65+
// Anchor links for headings and figures
66+
const LINK_ICON =
67+
'<svg xmlns="http://www.w3.org/2000/svg" width="0.75em" height="0.75em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>';
68+
69+
var postContent = document.querySelector(".post-content");
70+
if (postContent) {
71+
// Headings
72+
postContent
73+
.querySelectorAll("h2[id], h3[id], h4[id], h5[id], h6[id]")
74+
.forEach(function (h) {
75+
var a = document.createElement("a");
76+
a.className = "heading-anchor";
77+
a.href = "#" + h.id;
78+
a.setAttribute("aria-label", "Link to this section");
79+
a.innerHTML = LINK_ICON;
80+
h.appendChild(a);
81+
});
82+
83+
// Figures (img shortcode, tikz shortcode)
84+
// Auto-assign ids to figures that don't have one
85+
var figCounter = 0;
86+
postContent
87+
.querySelectorAll(".media-figure, .tikz-wrap")
88+
.forEach(function (fig) {
89+
if (!fig.id) {
90+
figCounter++;
91+
fig.id = "fig-" + figCounter;
92+
}
93+
var a = document.createElement("a");
94+
a.className = "fig-anchor";
95+
a.href = "#" + fig.id;
96+
a.setAttribute("aria-label", "Link to this figure");
97+
a.innerHTML = LINK_ICON;
98+
fig.appendChild(a);
99+
});
100+
101+
// Tables (table shortcode)
102+
var tblCounter = 0;
103+
postContent.querySelectorAll(".table-wrap").forEach(function (tbl) {
104+
if (!tbl.id) {
105+
tblCounter++;
106+
tbl.id = "tbl-" + tblCounter;
107+
}
108+
var a = document.createElement("a");
109+
a.className = "fig-anchor fig-anchor--top";
110+
a.href = "#" + tbl.id;
111+
a.setAttribute("aria-label", "Link to this table");
112+
a.innerHTML = LINK_ICON;
113+
tbl.appendChild(a);
114+
});
115+
}
64116
});
65117
})();
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{{ if .Get "width" }}
2-
<figure class="media-figure media-figure--sized" style="width:{{ .Get "width" }}%">
2+
<figure class="media-figure media-figure--sized" style="width:{{ .Get "width" }}%"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
33
{{ else }}
4-
<figure class="media-figure">
4+
<figure class="media-figure"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
55
{{ end }}
66
<img src="{{ .Get "src" }}"
7-
{{ with .Get "alt" }}alt="{{ . }}"{{ else }}alt=""{{ end }}
7+
alt="{{ with .Get "caption" }}{{ . }}{{ end }}"
88
loading="lazy" />
9+
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
910
</figure>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div class="table-wrap"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
2+
{{ .Inner | markdownify }}
3+
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
4+
</div>
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
<div class="tikz-figure">
2-
<script type="text/tikz">
3-
{{ .Inner }}
4-
</script>
1+
<div class="tikz-wrap"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
2+
<div class="tikz-figure">
3+
<script type="text/tikz">
4+
{{ .Inner }}
5+
</script>
6+
</div>
7+
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
58
</div>
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{{ if .Get "width" }}
2-
<figure class="media-figure media-figure--sized" style="width:{{ .Get "width" }}%">
2+
<figure class="media-figure media-figure--sized" style="width:{{ .Get "width" }}%"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
33
{{ else }}
4-
<figure class="media-figure">
4+
<figure class="media-figure"{{ with .Get "id" }} id="{{ . }}"{{ end }}>
55
{{ end }}
66
<video controls>
77
<source src="{{ .Get "src" }}" type="{{ with .Get "type" }}{{ . }}{{ else }}video/mp4{{ end }}">
88
Your browser does not support the video tag.
99
</video>
10+
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
1011
</figure>

0 commit comments

Comments
 (0)