add base structure

This commit is contained in:
jackyzha0 2021-07-18 09:35:42 -04:00
commit c01138a81c
26 changed files with 576 additions and 0 deletions

0
layouts/404.html Normal file
View file

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
{{ block "head" . }}
{{ end }}
<body>
{{ block "main" . }}
{{ end }}
</body>
</html>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
{{ partial "head.html" . }}
<body>
<div class="singlePage">
<!-- Begin actual content -->
{{partial "darkmode.html" .}}
<article>
{{if .Title}}<h1>{{ .Title }}</h1>{{end}}
{{- .Content -}}
</article>
{{partial "footer.html" .}}
</div>
{{- with resources.Get "darkmode.js" | minify -}}
<script>
{{.Content | safeJS }}
</script>
{{- end -}}
</body>
</html>

0
layouts/index.html Normal file
View file

View file

@ -0,0 +1,9 @@
<ol class="backlinks">
{{$curPage := strings.TrimRight "/" .Page.RelPermalink }}
{{$inbound := index $.Site.Data.linkIndex.index.backlinks $curPage}}
{{- range $inbound -}}
<li>
<a href="{{index . "source"}}">{{index . "source"}}</a>
</li>
{{- end -}}
</ol>

View file

@ -0,0 +1,16 @@
<div class='darkmode'>
<label id="toggle-label-light" for='darkmode-toggle' tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35;" xml:space="preserve">
<title>Light Mode</title>
<path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z" />
</svg>
</label>
<input class='toggle' id='darkmode-toggle' type='checkbox' tabindex="-1">
<label class='toggle-button' for='darkmode-toggle'></label>
<label id="toggle-label-dark" for='darkmode-toggle' tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background='new 0 0 100 100'" xml:space="preserve">
<title>Dark Mode</title>
<path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,22.008-14.65,35.369 c0,13.36,5.203,25.921,14.65,35.368s22.008,14.65,35.368,14.65c13.361,0,25.921-5.203,35.369-14.65 c3.872-3.871,7.064-8.328,9.491-13.246C97.826,68.608,97.611,67.309,96.76,66.458z" />
</svg>
</label>
</div>

View file

@ -0,0 +1,21 @@
<div>
<hr/>
{{partial "graph.html" .}}
<ul id="sub-nav">
<li><a href="/">↳ Take me home</a></li>
</ul>
</div>
<!-- Contact Info -->
<div id="contact_buttons" class="lt-centre">
<footer>
<p>made by {{ $.Site.Data.config.name }}, © {{ dateFormat "2006" now }}</p>
<a href="https://github.com/jackyzha0/quartz">source</a>
{{ if not .IsHome }}
<a href="/">home</a>
{{end}}
{{- range $.Site.Data.links.footer -}}
<a href="{{.link}}">{{.link_name}}</a>
{{- end -}}
</footer>
</div>

218
layouts/partials/graph.html Normal file
View file

@ -0,0 +1,218 @@
<script src="https://cdn.jsdelivr.net/npm/d3@6"></script>
<div id="graph-container"></div>
<style>
:root {
--g-node: {{.Site.Data.graphConfig.base.node}};
--g-node-active: {{.Site.Data.graphConfig.base.activeNode}};
--g-node-inactive: {{.Site.Data.graphConfig.base.inactiveNode}};
--g-link: {{.Site.Data.graphConfig.base.link}};
--g-link-active: {{.Site.Data.graphConfig.base.activeLink}};
}
</style>
<script>
const index = {{$.Site.Data.linkIndex.index}}
const links = {{$.Site.Data.linkIndex.links}}
const curPage = {{ strings.TrimRight "/" .Page.RelPermalink }}
const pathColors = {{$.Site.Data.graphConfig.paths}}
const parseIdsFromLinks = (links) => [...(new Set(links.flatMap(link => ([link.source, link.target]))))]
const data = {
nodes: parseIdsFromLinks(links).map(id => ({id})),
links,
}
const color = (d) => {
if (d.id === curPage) {
return "var(--g-node-active)"
}
for (const pathColor of pathColors) {
const path = Object.keys(pathColor)[0]
const colour = pathColor[path]
if (d.id.startsWith(path)) {
return colour
}
}
return "var(--g-node)"
}
const drag = simulation => {
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(1).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event,d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event,d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
const enableDrag = {{$.Site.Data.graphConfig.enableDrag}}
const noop = () => {}
return d3.drag()
.on("start", enableDrag ? dragstarted : noop)
.on("drag", enableDrag ? dragged : noop)
.on("end", enableDrag ? dragended : noop);
}
const height = 400
const width = document.getElementById("graph-container").offsetWidth
const simulation = d3.forceSimulation(data.nodes)
.force("charge", d3.forceManyBody().strength(-20))
.force("link", d3.forceLink(data.links)
.id(d => d.id)
)
.force("center", d3.forceCenter());
const svg = d3.select('#graph-container')
.append('svg')
.attr('width', width)
.attr('height', height)
.attr("viewBox", [-width / 2, -height / 2, width, height]);
// legend
const enableLegend = {{$.Site.Data.graphConfig.enableLegend}}
if (enableLegend) {
const legend = [
{"Current": "var(--g-node-active)"},
{"Note": "var(--g-node)"},
...pathColors
]
legend.forEach((legendEntry, i) => {
const key = Object.keys(legendEntry)[0]
const colour = legendEntry[key]
svg.append("circle").attr("cx", -width/2 + 20).attr("cy", height/2 - 30 * (i+1)).attr("r", 6).style("fill", colour)
svg.append("text").attr("x", -width/2 + 40).attr("y", height/2 - 30 * (i+1)).text(key).style("font-size", "15px").attr("alignment-baseline","middle")
})
}
// draw links between nodes
const link = svg.append("g")
.selectAll("line")
.data(data.links)
.join("line")
.attr("class", "link")
.attr("stroke", "var(--g-link)")
.attr("stroke-width", 2)
.attr("data-source", d => d.source.id)
.attr("data-target", d => d.target.id)
// svg groups
const graphNode = svg.append("g")
.selectAll("g")
.data(data.nodes)
.enter().append("g")
// draw individual nodes
const node = graphNode.append("circle")
.attr("class", "node")
.attr("id", (d) => d.id)
.attr("r", (d) => {
const numOut = index.links[d.id]?.length || 0
const numIn = index.backlinks[d.id]?.length || 0
return 3 + (numOut + numIn) / 4
})
.attr("fill", color)
.style("cursor", "pointer")
.on("click", (_, d) => {
window.location.href = d.id;
})
.on("mouseover", function (_, d) {
d3.selectAll(".node")
.transition()
.duration(100)
.attr("fill", "var(--g-node-inactive)")
const neighbours = parseIdsFromLinks([...(index.links[d.id] || []), ...(index.backlinks[d.id] || [])])
const neighbourNodes = d3.selectAll(".node").filter(d => neighbours.includes(d.id))
const currentId = d.id
const links = d3.selectAll(".link").filter(d => d.source.id === currentId || d.target.id === currentId)
// highlight neighbour nodes
neighbourNodes
.transition()
.duration(200)
.attr("fill", color)
// highlight links
links
.transition()
.duration(200)
.attr("stroke", "var(--g-link-active)")
// show text for self
d3.select(this.parentNode)
.select("text")
.raise()
.transition()
.duration(200)
.style("opacity", 1)
}).on("mouseleave", function (_,d) {
d3.selectAll(".node")
.transition()
.duration(200)
.attr("fill", color)
const currentId = d.id
const links = d3.selectAll(".link").filter(d => d.source.id === currentId || d.target.id === currentId)
links
.transition()
.duration(200)
.attr("stroke", "var(--g-link)")
d3.select(this.parentNode)
.select("text")
.transition()
.duration(200)
.style("opacity", 0)
})
.call(drag(simulation));
// draw labels
const labels = graphNode.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text((d) => d.id)
.style("opacity", 0)
.style("pointer-events", "none")
.call(drag(simulation));
// set panning
const enableZoom = {{$.Site.Data.graphConfig.enableZoom}}
if (enableZoom) {
svg.call(d3.zoom()
.extent([[0, 0], [width, height]])
.scaleExtent([0.25, 4])
.on("zoom", ({transform}) => {
link.attr("transform", transform);
node.attr("transform", transform);
labels.attr("transform", transform);
}));
}
// progress the simulation
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
labels
.attr("x", d => d.x)
.attr("y", d => d.y);
});
</script>

View file

@ -0,0 +1,24 @@
<head>
<link rel="preconnect" href="https://www.googletagmanager.com">
<link crossorigin rel="preconnect" href="https://www.google-analytics.com">
{{ template "_internal/google_analytics_async.html" . }}
<!-- Meta tags -->
<meta charset="UTF-8">
<meta name="description" content="{{$.Site.Data.config.description}}">
<title>{{$.Site.Data.config.page_title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="/icon.png" />
<!-- CSS Stylesheets and Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Source+Sans+Pro:wght@400;700&family=Fira+Code:wght@400;700&display=swap" rel="stylesheet">
{{ $css := slice "darkmode.scss" "syntax.scss"}}
{{range $css}}
{{$sass := resources.Get . | resources.ToCSS }}
{{with $sass | minify}}
<style>
{{.Content | safeCSS}}
</style>
{{end}}
{{end}}
</head>

View file