mirror of
				https://github.com/falsycat/ar.falsy.cat.git
				synced 2025-10-31 05:38:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			253 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!-- set data/config yaml file based on website language -->
 | ||
| {{ $config := cond (eq $.Site.Language.Lang "en") "config" (printf "config.%s" $.Site.Language.Lang) }}
 | ||
| {{ $data := index $.Site.Data $config }}
 | ||
| <head>
 | ||
|   <!-- Meta tags -->
 | ||
|   <meta charset="UTF-8" />
 | ||
|   <meta
 | ||
|     name="description"
 | ||
|     content="{{if .IsHome}}{{$data.description | default $.Site.Data.config.description}}{{else}}{{.Summary}}{{end}}"
 | ||
|   />
 | ||
|   <meta property="og:title" content="{{ .Title }}">
 | ||
|   <meta property="og:description" content="{{if .IsHome}}{{$data.description | default $.Site.Data.config.description}}{{else}}{{.Summary}}{{end}}">
 | ||
|   <meta property="og:type" content="website">
 | ||
|   <meta property="og:image" content="{{.Site.BaseURL}}icon.png">
 | ||
|   <meta property="og:url" content="{{ .Permalink }}">
 | ||
|   <meta property="og:width" content="200">
 | ||
|   <meta property="og:height" content="200">
 | ||
|   <meta name="twitter:card" content="summary" />
 | ||
|   <meta name="twitter:title" content="{{ .Title }}" />
 | ||
|   <meta name="twitter:description" content="{{if .IsHome}}{{$data.description | default $.Site.Data.config.description}}{{else}}{{.Summary}}{{end}}" />
 | ||
|   <meta name="twitter:image" content="{{.Site.BaseURL}}icon.png">
 | ||
|   {{ range $data.links }}
 | ||
|     {{ if strings.Contains .link "twitter.com" }}
 | ||
|       {{ $twitter_handle := index (split .link "/") (sub (len (split .link "/")) 1) }}
 | ||
|       <meta name="twitter:site" content="{{ $twitter_handle }}" />
 | ||
|     {{ end }}
 | ||
|   {{ end }}
 | ||
| 
 | ||
|   <title>
 | ||
|     {{ if .Title }}{{ .Title }}{{ else }}{{ $data.page_title | default $.Site.Data.config.page_title }}{{
 | ||
|     end }}
 | ||
|   </title>
 | ||
|   <meta name="viewport" content="width=device-width, initial-scale=1" />
 | ||
| 
 | ||
|   <!-- HTML Favicon -->
 | ||
|   {{ $favicon := $data.favicon  | default $.Site.Data.config.favicon | default (slice (dict "rel" "shortcut icon" "type" "image/png" "href" "icon.png")) }}
 | ||
|   {{ $type := (printf "%T" $favicon) }}
 | ||
|   {{ if eq $type "string" }}
 | ||
|   {{ $favicon | safeHTML }}
 | ||
|   {{ else }}
 | ||
|   {{ range $favicon }}
 | ||
|   <link rel="{{.rel}}" {{if .type}}type="{{.type}}"{{end}} {{if .sizes}}sizes="{{.sizes}}"{{end}} href="{{$.Site.BaseURL}}/{{.href}}" />
 | ||
|   {{- end }}
 | ||
|   {{ end }}
 | ||
| 
 | ||
|   <!-- CSS Stylesheets and Fonts -->
 | ||
|   {{$sass := resources.Match "styles/[!_]*.scss" }}
 | ||
|   {{$css := slice }}
 | ||
|   {{range $sass}}
 | ||
|   {{$scss := . | resources.ToCSS (dict "outputStyle" "compressed") }}
 | ||
|   {{$css = $css | append $scss}}
 | ||
|   {{end}}
 | ||
|   {{if $data.enableCallouts | default $.Site.Data.config.enableCallouts}}
 | ||
|     {{$scss := resources.Get "styles/_callouts.scss" | resources.ToCSS (dict "outputStyle" "compressed") }}
 | ||
|     {{$css = $css | append $scss}}
 | ||
|   {{end}}
 | ||
|   {{$finalCss := $css | resources.Concat "styles.css" | resources.Fingerprint "md5" | resources.Minify  }}
 | ||
|   <link href="{{$finalCss.Permalink}}" rel="stylesheet" />
 | ||
| 
 | ||
|   {{$lightSyntax := resources.Get "styles/_light_syntax.scss" | resources.ToCSS (dict "outputStyle" "compressed") | resources.Fingerprint "md5" | resources.Minify  }}
 | ||
|   <link href="{{$lightSyntax.Permalink}}" rel="stylesheet" id="theme-link">
 | ||
| 
 | ||
|    <!-- Base scripts -->
 | ||
|   {{$scripts := (slice "js/darkmode.js" "js/util.js")}}
 | ||
|   {{range $scripts}}
 | ||
|   {{$scriptname := .}}
 | ||
|   {{ $s := resources.Get $scriptname | resources.ExecuteAsTemplate $scriptname . | resources.Fingerprint "md5" | resources.Minify }}
 | ||
|   <script src="{{$s.Permalink}}"></script>
 | ||
|   {{end}}
 | ||
|   {{partial "katex.html" .}}
 | ||
| 
 | ||
|   {{partial "mermaid.html" .}}
 | ||
| 
 | ||
|   <script src="https://cdn.jsdelivr.net/npm/@floating-ui/core@1.2.1"></script>
 | ||
|   <script src="https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.2.1"></script>
 | ||
|   {{ $popover := resources.Get "js/popover.js" | resources.Fingerprint "md5" |
 | ||
|   resources.Minify }}
 | ||
|   <script defer src="{{$popover.Permalink}}"></script>
 | ||
| 
 | ||
|   <!-- Optional scripts -->
 | ||
|   {{ if $data.enableCodeBlockTitle | default $.Site.Data.config.enableCallouts }}
 | ||
|   {{ $codeTitle := resources.Get "js/code-title.js" | resources.Fingerprint "md5" | resources.Minify }}
 | ||
|   <script defer src="{{$codeTitle.Permalink}}"></script>
 | ||
|   {{end}}
 | ||
| 
 | ||
|   {{ if $data.enableCodeBlockCopy | default $.Site.Data.config.enableCodeBlockCopy }}
 | ||
|   {{ $clipboard := resources.Get "js/clipboard.js" | resources.Fingerprint "md5" | resources.Minify }}
 | ||
|   <script defer src="{{$clipboard.Permalink}}"></script>
 | ||
|   {{ end }}
 | ||
| 
 | ||
|   {{ if $data.enableCallouts | default $.Site.Data.config.enableCallouts }}
 | ||
|   {{ $callouts := resources.Get "js/callouts.js" | resources.Fingerprint "md5" | resources.Minify }}
 | ||
|   <script defer src="{{$callouts.Permalink}}"></script>
 | ||
|   {{ end }}
 | ||
| 
 | ||
|   <!--  Preload page vars  -->
 | ||
|   {{$linkIndex := resources.Get "indices/linkIndex.json" | resources.Fingerprint
 | ||
|   "md5" | resources.Minify | }} {{$contentIndex := resources.Get
 | ||
|   "indices/contentIndex.json" | resources.Fingerprint "md5" | resources.Minify
 | ||
|   }}
 | ||
|   <script>
 | ||
|     const SEARCH_ENABLED = {{.Site.Data.config.search.enableSemanticSearch}}
 | ||
|     const LATEX_ENABLED = {{.Site.Data.config.enableLatex}}
 | ||
|     const PRODUCTION = {{ hugo.IsProduction }}
 | ||
|     const BASE_URL = {{.Site.BaseURL}}
 | ||
|     const fetchData = Promise.all([
 | ||
|           fetch("{{ $linkIndex.Permalink }}")
 | ||
|             .then(data => data.json())
 | ||
|             .then(data => ({
 | ||
|               index: data.index,
 | ||
|               links: data.links,
 | ||
|             })),
 | ||
|           fetch("{{ $contentIndex.Permalink }}")
 | ||
|             .then(data => data.json()),
 | ||
|         ])
 | ||
|         .then(([{index, links}, content]) => ({
 | ||
|           index,
 | ||
|           links,
 | ||
|           content,
 | ||
|         }))
 | ||
| 
 | ||
|       const render = () => {
 | ||
|       // NOTE: everything within this callback will be executed for every page navigation. This is a good place to put JavaScript that loads or modifies data on the page, adds event listeners, etc. If you are only dealing with basic DOM replacement, use the init function
 | ||
| 
 | ||
|       const siteBaseURL = new URL(BASE_URL);
 | ||
|       const pathBase = siteBaseURL.pathname;
 | ||
|       const pathWindow = window.location.pathname;
 | ||
|       const isHome = pathBase == pathWindow;
 | ||
| 
 | ||
|       {{if $data.enableCodeBlockCopy | default $.Site.Data.config.enableCodeBlockCopy -}}
 | ||
|       addCopyButtons();
 | ||
|       {{ end }}
 | ||
| 
 | ||
|       {{if $data.enableSPA | default $.Site.Data.config.enableSPA -}}
 | ||
|       addTitleToCodeBlocks();
 | ||
|       {{ end }}
 | ||
| 
 | ||
|       {{if $data.enableCallouts | default $.Site.Data.config.enableCallouts -}}
 | ||
|       addCollapsibleCallouts();
 | ||
|       {{ end }}
 | ||
| 
 | ||
|       {{if $data.enableLinkPreview | default $.Site.Data.config.enableLinkPreview}}
 | ||
|       initPopover(
 | ||
|         {{strings.TrimRight "/" .Site.BaseURL }},
 | ||
|         {{$data.enableContextualBacklinks | default $.Site.Data.config.enableContextualBacklinks}}
 | ||
|       )
 | ||
|       {{end}}
 | ||
| 
 | ||
|       {{if $data.enableFooter | default $.Site.Data.config.enableFooter}}
 | ||
|       const footer = document.getElementById("footer")
 | ||
|       if (footer) {
 | ||
|         const container = document.getElementById("graph-container")
 | ||
|         // retry if the graph is not ready
 | ||
|         if (!container) return requestAnimationFrame(render)
 | ||
|         // clear the graph in case there is anything within it
 | ||
|         container.textContent = ""
 | ||
| 
 | ||
|         const drawGlobal = isHome && {{$.Site.Data.graphConfig.enableGlobalGraph}};
 | ||
|         drawGraph(
 | ||
|             {{strings.TrimRight "/" .Site.BaseURL}},
 | ||
|             drawGlobal,
 | ||
|             {{$.Site.Data.graphConfig.paths}},
 | ||
|             drawGlobal ? {{$.Site.Data.graphConfig.globalGraph}} : {{$.Site.Data.graphConfig.localGraph}}
 | ||
|           );
 | ||
| 
 | ||
|         }
 | ||
|       {{end}}
 | ||
| 
 | ||
|       {{if $data.enableMermaid | default $.Site.Data.config.enableMermaid}}
 | ||
|         var els = document.getElementsByClassName("mermaid");
 | ||
|         if (els.length > 0) {
 | ||
|           import('https://unpkg.com/mermaid@9/dist/mermaid.esm.min.mjs').then(
 | ||
|             (obj) => {
 | ||
|               // init forces mermaid to render mermaid markdown without waiting
 | ||
|               // for DOMContentLoaded event
 | ||
|               obj.default.init();
 | ||
|             }
 | ||
|           )
 | ||
|         }
 | ||
|       {{end}}
 | ||
|       
 | ||
|       // analytics
 | ||
|       function clickHandler(evt) {
 | ||
|         const target = evt.target 
 | ||
|         const classNames = target.className.split(" ")
 | ||
|         const broken = classNames.includes("broken")
 | ||
|         const internal = classNames.includes("internal-link")
 | ||
|         plausible("Link Click", {
 | ||
|           props: {
 | ||
|             href: target.href,
 | ||
|             broken,
 | ||
|             internal,
 | ||
|             graph: false,
 | ||
|           }
 | ||
|         })
 | ||
|       }
 | ||
| 
 | ||
|       const links = document.querySelectorAll("a")
 | ||
|       for (link of links) {
 | ||
|         if (link.className.includes("root-title")) {
 | ||
|           link.addEventListener('click', clickHandler, {once: true})
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     const init = (doc = document) => {
 | ||
|       // NOTE: everything within this callback will be executed for initial page navigation. This is a good place to put JavaScript that only replaces DOM nodes.
 | ||
|       {{if $data.enableCodeBlockCopy | default $.Site.Data.config.enableCodeBlockCopy -}}
 | ||
|       addCopyButtons();
 | ||
|       {{ end }}
 | ||
| 
 | ||
|       {{if $data.enableCodeBlockTitle | default $.Site.Data.config.enableCodeBlockTitle -}}
 | ||
|       addTitleToCodeBlocks();
 | ||
|       {{- end -}}
 | ||
|       {{if $data.enableLatex | default $.Site.Data.config.enableLatex}}
 | ||
|       renderMathInElement(doc.body, {
 | ||
|         delimiters: [
 | ||
|           {left: '$$', right: '$$', display: true},
 | ||
|           {left: '$', right: '$', display: false},
 | ||
|         ],
 | ||
|         macros: {
 | ||
|           '’': "'"
 | ||
|         },
 | ||
|         throwOnError : false
 | ||
|       });
 | ||
|       {{end}}
 | ||
|     };
 | ||
|   </script>
 | ||
|   {{if $data.enableSPA | default $.Site.Data.config.enableSPA}}
 | ||
|   {{ $router := resources.Get "js/router.js" | resources.Fingerprint "md5" |
 | ||
|   resources.Minify }}
 | ||
|   <script type="module">
 | ||
|     import { attachSPARouting } from "{{$router.Permalink}}"
 | ||
|     attachSPARouting(init, render)
 | ||
|   </script>
 | ||
|   {{else}}
 | ||
|   <script>
 | ||
|     window.Million = {
 | ||
|       navigate: (url) => (window.location.href = url),
 | ||
|       prefetch: () => {},
 | ||
|     }
 | ||
| 
 | ||
|     window.addEventListener("DOMContentLoaded", () => {
 | ||
|       init()
 | ||
|       render()
 | ||
|     })
 | ||
|   </script>
 | ||
|   {{end}}
 | ||
|   {{ $trimmedURL := trim (index (split .Site.BaseURL "://") 1) "/" }}
 | ||
|   <script defer data-domain="{{$trimmedURL}}" src="https://plausible.io/js/script.js"></script>
 | ||
|   <script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
 | ||
| </head>
 |