mirror of
				https://github.com/imfing/hextra.git
				synced 2025-10-31 09:54:50 -04:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			v0.11.1
			...
			122-improv
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 9fc253dff5 | ||
|   | 0125822785 | ||
|   | 1e1d1c8716 | ||
|   | 1048ee47d7 | ||
|   | 5842f893a3 | ||
|   | 78ce7c2f2e | ||
|   | 0652772c15 | ||
|   | 13e4eb3414 | ||
|   | 529fcd8a62 | ||
|   | 21a13c49f9 | ||
|   | 98d0a3dc73 | ||
|   | 24f3178ea8 | ||
|   | 230cc438b7 | ||
|   | 214cb7994f | ||
|   | 792ad4b569 | 
| @@ -1,12 +1,13 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="{{ .Site.Language.Lang }}"> | ||||
|   {{- partial "head.html" . -}} | ||||
|   {{ partial "head.html" . -}} | ||||
|   <body dir="ltr"> | ||||
|     {{- partial "navbar.html" . -}} | ||||
|     {{ partial "navbar.html" . -}} | ||||
|     {{- block "main" . }}{{ end -}} | ||||
|     {{- if or (eq .Site.Params.footer.enable nil) (.Site.Params.footer.enable) }} | ||||
|       {{ partial "footer.html" . }} | ||||
|     {{ end }} | ||||
|     {{ end -}} | ||||
|   </body> | ||||
|   {{ partial "scripts.html" . }} | ||||
|   {{ partialCached "scripts.html" . }} | ||||
|   {{ partial "third-party/scripts.html" . }} | ||||
| </html> | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
|     {{- $currentPage := . -}} | ||||
|     {{- range .Site.Menus.main -}} | ||||
|       {{- if eq .Params.type "search" -}} | ||||
|         {{- partial "search.html" (dict "params" .Params) -}} | ||||
|         {{- partialCached "search.html" $currentPage -}} | ||||
|       {{- else -}} | ||||
|         {{- $external := strings.HasPrefix .URL "http" -}} | ||||
|         {{/* Display icon menu item */}} | ||||
|   | ||||
| @@ -27,49 +27,6 @@ | ||||
|     <script defer src="{{ $flexSearchJS.RelPermalink }}" integrity="{{ $flexSearchJS.Data.Integrity }}"></script> | ||||
|     <script defer src="{{ $jsSearch.RelPermalink }}" integrity="{{ $jsSearch.Data.Integrity }}"></script> | ||||
|   {{- else -}} | ||||
|     {{- warnf `search type "%s" is not supported` $searchType -}} | ||||
|     {{- errorf `search type "%s" is not supported` $searchType -}} | ||||
|   {{- end -}} | ||||
| {{- end -}} | ||||
|  | ||||
| {{/* Mermaid */}} | ||||
| {{/* FIXME: need to investigate .Page.Store hasMermaid is set for homepage */}} | ||||
| {{- if and (.Page.Store.Get "hasMermaid") (not .Page.IsHome) -}} | ||||
|   {{- $mermaidJS := resources.Get "lib/mermaid/mermaid.min.js" | fingerprint -}} | ||||
|   <script defer src="{{ $mermaidJS.RelPermalink }}" integrity="{{ $mermaidJS.Data.Integrity }}"></script> | ||||
|   <script> | ||||
|     document.addEventListener("DOMContentLoaded", function () { | ||||
|       const theme = document.documentElement.classList.contains("dark") ? "dark" : "default"; | ||||
|       mermaid.initialize({ startOnLoad: true, theme: theme }); | ||||
|     }); | ||||
|   </script> | ||||
| {{- end -}} | ||||
|  | ||||
| {{/* KaTex */}} | ||||
| {{- if .Page.Params.math -}} | ||||
|   {{- $katexCSS := resources.Get "lib/katex/katex.min.css" | fingerprint -}} | ||||
|   {{- $katexJS := resources.Get "lib/katex/katex.min.js" | fingerprint -}} | ||||
|   {{- $mhchemJS := resources.Get "lib/katex/mhchem.min.js" | fingerprint -}} | ||||
|   {{- $katexAutoRenderJS := resources.Get "lib/katex/auto-render.min.js" | fingerprint -}} | ||||
|   <link type="text/css" rel="stylesheet" href="{{ $katexCSS.RelPermalink }}" integrity="{{ $katexCSS.Data.Integrity }}" /> | ||||
|   <script defer src="{{ $katexJS.RelPermalink }}" integrity="{{ $katexJS.Data.Integrity }}"></script> | ||||
|   <script defer src="{{ $katexAutoRenderJS.RelPermalink }}" integrity="{{ $katexAutoRenderJS.Data.Integrity }}"></script> | ||||
|   <script defer src="{{ $mhchemJS.RelPermalink }}" integrity="{{ $mhchemJS.Data.Integrity }}"></script> | ||||
|   {{ $katexFonts := resources.Match "lib/katex/fonts/*" }} | ||||
|   {{- range $katexFonts -}} | ||||
|     {{ .Publish }} | ||||
|   {{- end -}} | ||||
|   <script> | ||||
|     // TODO: make render options configurable | ||||
|     document.addEventListener("DOMContentLoaded", function () { | ||||
|       renderMathInElement(document.body, { | ||||
|         delimiters: [ | ||||
|           { left: "$$", right: "$$", display: true }, | ||||
|           { left: "$", right: "$", display: false }, | ||||
|           { left: "\\(", right: "\\)", display: false }, | ||||
|           { left: "\\[", right: "\\]", display: true }, | ||||
|         ], | ||||
|         throwOnError: false, | ||||
|       }); | ||||
|     }); | ||||
|   </script> | ||||
| {{ end }} | ||||
|   | ||||
| @@ -6,33 +6,60 @@ | ||||
| {{- $sidebarClass := cond $disableSidebar (cond $displayPlaceholder "md:hidden xl:block" "md:hidden") "md:sticky" -}} | ||||
|  | ||||
| {{- $navRoot := cond (eq site.Home.Type "docs") site.Home $context.FirstSection -}} | ||||
| {{- $navPages := union $navRoot.RegularPages $navRoot.Sections -}} | ||||
| {{- $pageURL := $context.RelPermalink -}} | ||||
|  | ||||
|  | ||||
| <aside class="sidebar-container flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:self-start max-md:[transform:translate3d(0,-100%,0)] {{ $sidebarClass }}"> | ||||
|   <!-- Search bar on small screen --> | ||||
|   <div class="px-4 pt-4 md:hidden"> | ||||
|     {{ partial "search.html" }} | ||||
|   </div> | ||||
|   {{/* Search bar on small screen */}} | ||||
|   {{- partialCached "sidebar/mobile-search" . -}} | ||||
|  | ||||
|   <div class="hextra-scrollbar overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]"> | ||||
|     <ul class="flex flex-col gap-1 md:hidden"> | ||||
|       <!-- Nav --> | ||||
|       {{ template "sidebar-main" (dict "context" site.Home "pageURL" $pageURL "page" $context "toc" true) -}} | ||||
|       {{ template "sidebar-footer" }} | ||||
|       {{/* Mobile Navigation */}} | ||||
|       {{ $treeMobile := partialCached "sidebar/section-tree" site.Home site.Home }} | ||||
|       {{ partial "sidebar/render-tree" (dict "context" site.Home "page" $context "tree" ($treeMobile | unmarshal)) }} | ||||
|       {{ partialCached "sidebar/extra" $context }} | ||||
|     </ul> | ||||
|  | ||||
|     <!-- Sidebar on large screen --> | ||||
|     {{- if $disableSidebar -}} | ||||
|       {{- if $displayPlaceholder }}<div class="max-xl:hidden h-0 w-64 shrink-0"></div>{{ end -}} | ||||
|       {{ .context.Scratch.Set "enableFooterSwitches" true }} | ||||
|     {{- else -}} | ||||
|     {{/* Sidebar on large screen */}} | ||||
|     <ul class="flex flex-col gap-1 max-md:hidden"> | ||||
|         {{ template "sidebar-main" (dict "context" $navRoot "page" $context  "pageURL" $pageURL) }} | ||||
|         {{ template "sidebar-footer" }} | ||||
|       {{ $tree := partialCached "sidebar/section-tree" $navRoot $navRoot }} | ||||
|       {{ partial "sidebar/render-tree" (dict "context" $navRoot "page" $context "tree" ($tree | unmarshal)) }} | ||||
|       {{ partialCached "sidebar/extra" $context }} | ||||
|     </ul> | ||||
|     {{ end -}} | ||||
|   </div> | ||||
|  | ||||
|   {{ partial "sidebar/switches" (dict "context" $context "disableSidebar" $disableSidebar) }} | ||||
| </aside> | ||||
|  | ||||
| {{- define "partials/sidebar/mobile-search" -}} | ||||
|   <div class="px-4 pt-4 md:hidden"> | ||||
|     {{- partialCached "search.html" . -}} | ||||
|   </div> | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-item-link" -}} | ||||
|   {{- $external := strings.HasPrefix .link "http" -}} | ||||
|   <a | ||||
|     class="flex items-center justify-between gap-2 cursor-pointer rounded px-2 py-1.5 text-sm transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] | ||||
|     {{- if .active }} | ||||
|       sidebar-active-item bg-primary-100 font-semibold text-primary-800 contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500 | ||||
|     {{- else }} | ||||
|       text-gray-500 hover:bg-gray-100 hover:text-gray-900 contrast-more:border contrast-more:border-transparent contrast-more:text-gray-900 contrast-more:hover:border-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:dark:text-gray-50 contrast-more:dark:hover:border-gray-50 | ||||
|     {{- end -}}" | ||||
|     href="{{ .link }}" | ||||
|     {{ if $external }}target="_blank" rel="noreferer"{{ end }} | ||||
|   > | ||||
|     {{- .title | htmlUnescape | safeHTML -}} | ||||
|     {{- with .context }} | ||||
|       {{- if or .RegularPages .Sections .section }}{{ partialCached "sidebar/collapsible-button" . }}{{ end -}} | ||||
|     {{ end -}} | ||||
|   </a> | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "partials/sidebar/switches" -}} | ||||
|   {{- $context := .context -}} | ||||
|   {{- $disableSidebar := .disableSidebar -}} | ||||
|   {{/* Hide theme switch when sidebar is disabled */}} | ||||
|   {{ $switchesClass := cond $disableSidebar "md:hidden" "" -}} | ||||
|   {{ $displayThemeToggle := (site.Params.theme.displayToggle | default true) -}} | ||||
| @@ -49,120 +76,4 @@ | ||||
|       {{- end -}} | ||||
|     </div> | ||||
|   {{- end -}} | ||||
| </aside> | ||||
|  | ||||
| {{- define "sidebar-main" -}} | ||||
|   {{ template "sidebar-tree" (dict "context" .context "level" 0 "page" .page "pageURL" .pageURL "toc" (.toc | default false)) }} | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-tree" -}} | ||||
|   {{- if ge .level 4 -}} | ||||
|     {{- return -}} | ||||
|   {{- end -}} | ||||
|  | ||||
|   {{- $context := .context -}} | ||||
|   {{- $page := .page }} | ||||
|   {{- $pageURL := .page.RelPermalink -}} | ||||
|   {{- $level := .level -}} | ||||
|   {{- $toc := .toc | default false -}} | ||||
|  | ||||
|   {{- with $items := union .context.RegularPages .context.Sections -}} | ||||
|     {{- if eq $level 0 -}} | ||||
|       {{- range $items.ByWeight }} | ||||
|         {{- $active := eq $pageURL .RelPermalink -}} | ||||
|         {{- $shouldOpen := or (.Params.sidebar.open) (.IsAncestor $page) $active | default true }} | ||||
|         <li class="{{ if $shouldOpen }}open{{ end }}"> | ||||
|           {{- template "sidebar-item-link" dict "context" . "active" $active "title" .LinkTitle "link" .RelPermalink -}} | ||||
|           {{- if and $toc $active -}} | ||||
|             {{- template "sidebar-toc" dict "page" . -}} | ||||
|           {{- end -}} | ||||
|           {{- template "sidebar-tree" dict "context" . "page" $page "pageURL" $pageURL "level" (add $level 1) "toc" $toc -}} | ||||
|         </li> | ||||
|       {{- end -}} | ||||
|     {{- else -}} | ||||
|       <div class="pt-1 ltr:pr-0 overflow-hidden transition-all ease-in-out duration-200"> | ||||
|         <ul class='relative flex flex-col gap-1 before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] ltr:ml-3 ltr:pl-3 ltr:before:left-0 rtl:mr-3 rtl:pr-3 rtl:before:right-0 dark:before:bg-neutral-800'> | ||||
|           {{- range $items.ByWeight }} | ||||
|             {{- $active := eq $pageURL .RelPermalink -}} | ||||
|             {{- $shouldOpen := or (.Params.sidebar.open) (.IsAncestor $page) $active | default true }} | ||||
|             {{- $title := .LinkTitle | default .File.BaseFileName -}} | ||||
|             <li class="flex flex-col gap-1 {{ if $shouldOpen }}open{{ end }}"> | ||||
|               {{- template "sidebar-item-link" dict "context" . "active" $active "title" $title "link" .RelPermalink -}} | ||||
|               {{- if and $toc $active -}} | ||||
|                 {{ template "sidebar-toc" dict "page" . }} | ||||
|               {{- end }} | ||||
|               {{ template "sidebar-tree" dict "context" . "page" $page "pageURL" $pageURL "level" (add $level 1) "toc" $toc }} | ||||
|             </li> | ||||
|           {{- end -}} | ||||
|         </ul> | ||||
|       </div> | ||||
|     {{- end -}} | ||||
|   {{- end }} | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-toc" -}} | ||||
|   {{ $page := .page }} | ||||
|   {{ with $page.Fragments.Headings }} | ||||
|     <ul class='flex flex-col gap-1 relative before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] dark:before:bg-neutral-800 ltr:pl-3 ltr:before:left-0 rtl:pr-3 rtl:before:right-0 ltr:ml-3 rtl:mr-3'> | ||||
|       {{- range . }} | ||||
|         {{- with .Headings }} | ||||
|           {{- range . -}} | ||||
|             <li> | ||||
|               <a | ||||
|                 href="#{{ anchorize .ID }}" | ||||
|                 class="flex rounded px-2 py-1.5 text-sm transition-colors [word-break:break-word] cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:border flex gap-2 before:opacity-25 before:content-['#'] text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:text-gray-900 contrast-more:dark:text-gray-50 contrast-more:border-transparent contrast-more:hover:border-gray-900 contrast-more:dark:hover:border-gray-50" | ||||
|               > | ||||
|                 {{- .Title -}} | ||||
|               </a> | ||||
|             </li> | ||||
|           {{ end -}} | ||||
|         {{ end -}} | ||||
|       {{ end -}} | ||||
|     </ul> | ||||
|   {{ end }} | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-footer" -}} | ||||
|   {{- range site.Menus.sidebar -}} | ||||
|     {{- $name := or (T .Identifier) .Name -}} | ||||
|     {{ if eq .Params.type "separator" }} | ||||
|       <li class="[word-break:break-word] mt-5 mb-2 px-2 py-1.5 text-sm font-semibold text-gray-900 first:mt-0 dark:text-gray-100"> | ||||
|         <span class="cursor-default">{{ $name }}</span> | ||||
|       </li> | ||||
|     {{ else }} | ||||
|       <li>{{ template "sidebar-item-link" dict "active" false "title" $name "link" (.URL | relLangURL) }}</li> | ||||
|     {{ end }} | ||||
|   {{- end -}} | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-item-link" -}} | ||||
|   {{- $external := strings.HasPrefix .link "http" -}} | ||||
|   {{- $open := .open | default true -}} | ||||
|   <a | ||||
|     class="flex items-center justify-between gap-2 cursor-pointer rounded px-2 py-1.5 text-sm transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] | ||||
|     {{- if .active }} | ||||
|       sidebar-active-item bg-primary-100 font-semibold text-primary-800 contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500 | ||||
|     {{- else }} | ||||
|       text-gray-500 hover:bg-gray-100 hover:text-gray-900 contrast-more:border contrast-more:border-transparent contrast-more:text-gray-900 contrast-more:hover:border-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:dark:text-gray-50 contrast-more:dark:hover:border-gray-50 | ||||
|     {{- end -}}" | ||||
|     href="{{ .link }}" | ||||
|     {{ if $external }}target="_blank" rel="noreferer"{{ end }} | ||||
|   > | ||||
|     {{- .title -}} | ||||
|     {{- with .context }} | ||||
|       {{- if or .RegularPages .Sections }} | ||||
|         <span class="hextra-sidebar-collapsible-button"> | ||||
|           {{- template "sidebear-collapsible-button" -}} | ||||
|         </span> | ||||
|       {{- end }} | ||||
|     {{ end -}} | ||||
|   </a> | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebar-separator" -}} | ||||
|   <div class="mt-4 border-t py-4 dark:border-neutral-800 contrast-more:border-neutral-400 dark:contrast-more:border-neutral-400" /> | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "sidebear-collapsible-button" -}} | ||||
|   <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="h-[18px] min-w-[18px] rounded-sm p-0.5 hover:bg-gray-800/5 dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="origin-center transition-transform rtl:-rotate-180"></path></svg> | ||||
| {{- end -}} | ||||
|   | ||||
							
								
								
									
										3
									
								
								layouts/partials/sidebar/collapsible-button.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								layouts/partials/sidebar/collapsible-button.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <span class="hextra-sidebar-collapsible-button"> | ||||
|   <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="h-[18px] min-w-[18px] rounded-sm p-0.5 hover:bg-gray-800/5 dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="origin-center transition-transform rtl:-rotate-180"></path></svg> | ||||
| </span> | ||||
							
								
								
									
										10
									
								
								layouts/partials/sidebar/extra.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								layouts/partials/sidebar/extra.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| {{- range site.Menus.sidebar -}} | ||||
|   {{- $name := or (T .Identifier) .Name -}} | ||||
|   {{ if eq .Params.type "separator" }} | ||||
|     <li class="[word-break:break-word] mt-5 mb-2 px-2 py-1.5 text-sm font-semibold text-gray-900 first:mt-0 dark:text-gray-100"> | ||||
|       <span class="cursor-default">{{ $name }}</span> | ||||
|     </li> | ||||
|   {{ else }} | ||||
|     <li>{{ template "sidebar-item-link" (dict "active" false "title" $name "link" (.URL | relLangURL)) }}</li> | ||||
|   {{ end }} | ||||
| {{- end -}} | ||||
| @@ -0,0 +1,15 @@ | ||||
| {{- $entry := . -}} | ||||
|  | ||||
| <div class="pt-1 ltr:pr-0 overflow-hidden transition-all ease-in-out duration-200"> | ||||
|   <ul class='relative flex flex-col gap-1 before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] ltr:ml-3 ltr:pl-3 ltr:before:left-0 rtl:mr-3 rtl:pr-3 rtl:before:right-0 dark:before:bg-neutral-800'> | ||||
|     {{- range $entry }} | ||||
|       {{- $shouldOpen := .open | default false }} | ||||
|       <li class="flex flex-col gap-1 {{ if $shouldOpen }}open{{ end }}"> | ||||
|         {{- template "sidebar-item-link" (dict "context" . "active" false "title" .title "link" .link) -}} | ||||
|         {{- if .section -}} | ||||
|           {{- partial "sidebar/render-tree-branch-without-leaf" .section -}} | ||||
|         {{- end -}} | ||||
|       </li> | ||||
|     {{- end -}} | ||||
|   </ul> | ||||
| </div> | ||||
							
								
								
									
										19
									
								
								layouts/partials/sidebar/render-tree-branch.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								layouts/partials/sidebar/render-tree-branch.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| {{- $context := .context -}} | ||||
| {{- $page := .page -}} | ||||
| {{- $entry := .entry -}} | ||||
| {{- $pageLink := .page.RelPermalink -}} | ||||
|  | ||||
| <div class="pt-1 ltr:pr-0 overflow-hidden transition-all ease-in-out duration-200"> | ||||
|   <ul class='relative flex flex-col gap-1 before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] ltr:ml-3 ltr:pl-3 ltr:before:left-0 rtl:mr-3 rtl:pr-3 rtl:before:right-0 dark:before:bg-neutral-800'> | ||||
|     {{- range $entry }} | ||||
|       {{- $active := eq $pageLink .link -}} | ||||
|       {{- $shouldOpen := or (.open) (hasPrefix $pageLink .link) $active | default true }} | ||||
|       <li class="flex flex-col gap-1 {{ if $shouldOpen }}open{{ end }}"> | ||||
|         {{- template "sidebar-item-link" (dict "context" . "active" $active "title" .title "link" .link) -}} | ||||
|         {{- if .section -}} | ||||
|           {{- partial "sidebar/render-tree-branch" (dict "context" $context "entry" .section "page" $page) -}} | ||||
|         {{- end -}} | ||||
|       </li> | ||||
|     {{- end -}} | ||||
|   </ul> | ||||
| </div> | ||||
							
								
								
									
										18
									
								
								layouts/partials/sidebar/render-tree.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								layouts/partials/sidebar/render-tree.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| {{- $context := .context -}} | ||||
| {{- $page := .page -}} | ||||
| {{- $pageLink := .page.RelPermalink -}} | ||||
| {{- range .tree -}} | ||||
|   {{- $active := eq $pageLink .link -}} | ||||
|   {{- $containsPage := hasPrefix $pageLink .link -}} | ||||
|   {{- $shouldOpen := or (.open) $containsPage $active | default false }} | ||||
|   <li class="{{ if $shouldOpen }}open{{ end }}"> | ||||
|     {{- template "sidebar-item-link" (dict "context" . "active" $active "title" .title "link" .link) -}} | ||||
|     {{- if .section -}} | ||||
|       {{- if not $containsPage -}} | ||||
|         {{- partialCached "sidebar/render-tree-branch-without-leaf" .section .section -}} | ||||
|       {{- else -}} | ||||
|         {{- partial "sidebar/render-tree-branch" (dict "context" $context "entry" .section "page" $page) -}} | ||||
|       {{- end -}} | ||||
|     {{- end -}} | ||||
|   </li> | ||||
| {{ end }} | ||||
							
								
								
									
										51
									
								
								layouts/partials/sidebar/section-tree.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								layouts/partials/sidebar/section-tree.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| {{ $context := . -}} | ||||
|  | ||||
| {{- $pages := union .RegularPages .Sections -}} | ||||
| {{- $pages = where $pages "Params.sidebar.exclude" "!=" true -}} | ||||
|  | ||||
| {{- $data := slice -}} | ||||
|  | ||||
| {{- range $pages.ByWeight -}} | ||||
|   {{ $structure := (partial "sidebar/section-walk" .) | unmarshal -}} | ||||
|   {{ $data = $data | append $structure -}} | ||||
| {{ end -}} | ||||
|  | ||||
| {{- define "partials/sidebar/section-walk" -}} | ||||
|   {{- with . -}} | ||||
|   { | ||||
|     "title": "{{ .LinkTitle | default .File.BaseFileName }}", | ||||
|     "link": "{{ .RelPermalink }}", | ||||
|     "toc": {{ partial "sidebar/section-page-toc" . }}, | ||||
|     "open": {{ .Params.sidebar.open | default false }} | ||||
|     {{- if .IsSection }}, | ||||
|     "section": [ | ||||
|       {{ $pages := union .RegularPages .Sections -}} | ||||
|       {{ $pages = where $pages "Params.sidebar.exclude" "!=" true -}} | ||||
|       {{ range $index, $page := $pages.ByWeight -}} | ||||
|         {{ partial "sidebar/section-walk" . }}{{ if not (ge $index (sub (len $pages) 1)) }},{{ end -}} | ||||
|       {{ end -}} | ||||
|     ] | ||||
|     {{ end -}} | ||||
|   } | ||||
|   {{- end }} | ||||
| {{- end -}} | ||||
|  | ||||
| {{- define "partials/sidebar/section-page-toc" -}} | ||||
|   {{/* Get level 2 headings list used mainly for mobile navigation */}} | ||||
|   [ | ||||
|     {{- with .Fragments.Headings -}} | ||||
|       {{/* Loop over level 1 headings */}} | ||||
|       {{- range . }} | ||||
|         {{- with .Headings }} | ||||
|           {{ $headings := . }} | ||||
|           {{- range $index, $heading := $headings }} | ||||
|             {{ $heading.Title | jsonify (dict "noHTMLEscape" true) }} | ||||
|             {{- if not (ge $index (sub (len $headings) 1)) }},{{ end -}} | ||||
|           {{ end -}} | ||||
|         {{- end -}} | ||||
|       {{ end -}} | ||||
|     {{- end -}} | ||||
|   ] | ||||
| {{- end -}} | ||||
|  | ||||
| {{ return ($data | jsonify (dict "noHTMLEscape" true)) }} | ||||
							
								
								
									
										21
									
								
								layouts/partials/sidebar/toc.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								layouts/partials/sidebar/toc.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| {{ $page := . }} | ||||
| {{ with $page.Fragments.Headings }} | ||||
|   <ul | ||||
|     class='flex flex-col gap-1 relative before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] dark:before:bg-neutral-800 ltr:pl-3 ltr:before:left-0 rtl:pr-3 rtl:before:right-0 ltr:ml-3 rtl:mr-3' | ||||
|   > | ||||
|     {{- range . }} | ||||
|       {{- with .Headings }} | ||||
|         {{- range . -}} | ||||
|           <li> | ||||
|             <a | ||||
|               href="#{{ anchorize .ID }}" | ||||
|               class="flex rounded px-2 py-1.5 text-sm transition-colors [word-break:break-word] cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:border gap-2 before:opacity-25 before:content-['#'] text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:text-gray-900 contrast-more:dark:text-gray-50 contrast-more:border-transparent contrast-more:hover:border-gray-900 contrast-more:dark:hover:border-gray-50" | ||||
|             > | ||||
|               {{- .Title -}} | ||||
|             </a> | ||||
|           </li> | ||||
|         {{ end -}} | ||||
|       {{ end -}} | ||||
|     {{ end -}} | ||||
|   </ul> | ||||
| {{ end }} | ||||
							
								
								
									
										42
									
								
								layouts/partials/third-party/scripts.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								layouts/partials/third-party/scripts.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| {{/* Mermaid */}} | ||||
| {{/* FIXME: need to investigate .Page.Store hasMermaid is set for homepage */}} | ||||
| {{- if and (.Page.Store.Get "hasMermaid") (not .Page.IsHome) -}} | ||||
|   {{- $mermaidJS := resources.Get "lib/mermaid/mermaid.min.js" | fingerprint -}} | ||||
|   <script defer src="{{ $mermaidJS.RelPermalink }}" integrity="{{ $mermaidJS.Data.Integrity }}"></script> | ||||
|   <script> | ||||
|     document.addEventListener("DOMContentLoaded", function () { | ||||
|       const theme = document.documentElement.classList.contains("dark") ? "dark" : "default"; | ||||
|       mermaid.initialize({ startOnLoad: true, theme: theme }); | ||||
|     }); | ||||
|   </script> | ||||
| {{- end -}} | ||||
|  | ||||
| {{/* KaTex */}} | ||||
| {{- if .Page.Params.math -}} | ||||
|   {{- $katexCSS := resources.Get "lib/katex/katex.min.css" | fingerprint -}} | ||||
|   {{- $katexJS := resources.Get "lib/katex/katex.min.js" | fingerprint -}} | ||||
|   {{- $mhchemJS := resources.Get "lib/katex/mhchem.min.js" | fingerprint -}} | ||||
|   {{- $katexAutoRenderJS := resources.Get "lib/katex/auto-render.min.js" | fingerprint -}} | ||||
|   <link type="text/css" rel="stylesheet" href="{{ $katexCSS.RelPermalink }}" integrity="{{ $katexCSS.Data.Integrity }}" /> | ||||
|   <script defer src="{{ $katexJS.RelPermalink }}" integrity="{{ $katexJS.Data.Integrity }}"></script> | ||||
|   <script defer src="{{ $katexAutoRenderJS.RelPermalink }}" integrity="{{ $katexAutoRenderJS.Data.Integrity }}"></script> | ||||
|   <script defer src="{{ $mhchemJS.RelPermalink }}" integrity="{{ $mhchemJS.Data.Integrity }}"></script> | ||||
|   {{ $katexFonts := resources.Match "lib/katex/fonts/*" }} | ||||
|   {{- range $katexFonts -}} | ||||
|     {{ .Publish }} | ||||
|   {{- end -}} | ||||
|   <script> | ||||
|     // TODO: make render options configurable | ||||
|     document.addEventListener("DOMContentLoaded", function () { | ||||
|       renderMathInElement(document.body, { | ||||
|         delimiters: [ | ||||
|           { left: "$$", right: "$$", display: true }, | ||||
|           { left: "$", right: "$", display: false }, | ||||
|           { left: "\\(", right: "\\)", display: false }, | ||||
|           { left: "\\[", right: "\\]", display: true }, | ||||
|         ], | ||||
|         throwOnError: false, | ||||
|       }); | ||||
|     }); | ||||
|   </script> | ||||
| {{ end }} | ||||
| @@ -3,7 +3,8 @@ | ||||
|     "dev:theme": "hugo server --logLevel=debug --config=hugo.yaml,../dev.toml --environment=theme --source=exampleSite --themesDir=../.. --disableFastRender -D --port 1313", | ||||
|     "dev": "hugo server --source=exampleSite --themesDir=../.. --disableFastRender -D --port 1313", | ||||
|     "build:css": "npx postcss --config postcss.config.js --env production assets/css/styles.css -o assets/css/compiled/main.css", | ||||
|     "build": "hugo --gc --minify --themesDir=../.. --source=exampleSite" | ||||
|     "build": "hugo --gc --minify --themesDir=../.. --source=exampleSite", | ||||
|     "metrics": "hugo --themesDir=../.. --source=exampleSite --templateMetrics --templateMetricsHints" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user