add base structure
This commit is contained in:
		
						commit
						c01138a81c
					
				
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| .DS_Store | ||||
| public | ||||
| resources | ||||
| .idea | ||||
| content/.obsidian | ||||
							
								
								
									
										21
									
								
								LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| MIT License | ||||
| 
 | ||||
| Copyright (c) 2021 jackyzha0 | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| # quartz | ||||
| Simple second brain and digital garden. | ||||
| 
 | ||||
| ```shell | ||||
| # Installation | ||||
| go install github.com/jackyzha0/hugo-obsidian | ||||
| 
 | ||||
| # Run | ||||
| hugo-obsidian -input=content -output=data | ||||
| ``` | ||||
							
								
								
									
										26
									
								
								assets/darkmode.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								assets/darkmode.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| // Darkmode toggle
 | ||||
| const toggleSwitch = document.querySelector('#darkmode-toggle') | ||||
| 
 | ||||
| const userPref = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark' | ||||
| const currentTheme = localStorage.getItem('theme') ?? userPref | ||||
| 
 | ||||
| if (currentTheme) { | ||||
|   document.documentElement.setAttribute('saved-theme', currentTheme); | ||||
|   if (currentTheme === 'dark') { | ||||
|     toggleSwitch.checked = true | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const switchTheme = (e) => { | ||||
|   if (e.target.checked) { | ||||
|     document.documentElement.setAttribute('saved-theme', 'dark') | ||||
|     localStorage.setItem('theme', 'dark') | ||||
|   } | ||||
|   else { | ||||
|     document.documentElement.setAttribute('saved-theme', 'light') | ||||
|     localStorage.setItem('theme', 'light') | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // listen for toggle
 | ||||
| toggleSwitch.addEventListener('change', switchTheme, false) | ||||
							
								
								
									
										67
									
								
								assets/darkmode.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								assets/darkmode.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| 
 | ||||
| .darkmode { | ||||
|   text-align: right; | ||||
| 
 | ||||
|   & > .toggle { | ||||
|     display: none; | ||||
|     box-sizing: border-box; | ||||
| 
 | ||||
|     &:checked + .toggle-button:after { | ||||
|       left: 50%; | ||||
|     } | ||||
| 
 | ||||
|     & + .toggle-button { | ||||
|       box-sizing: border-box; | ||||
|       outline: 0; | ||||
|       display: inline-block; | ||||
|       width: 3em; | ||||
|       height: 1.5em; | ||||
|       position: relative; | ||||
|       cursor: pointer; | ||||
|       border: 2px solid var(--gray); | ||||
|       user-select: none; | ||||
|       padding: 2px; | ||||
|       transition: all 0.2s ease; | ||||
|       border-radius: 2em; | ||||
| 
 | ||||
|       &:after, &:before { | ||||
|         position: relative; | ||||
|         display: block; | ||||
|         box-sizing: border-box; | ||||
|         content: ""; | ||||
|         width: 50%; | ||||
|         height: 100%; | ||||
|       } | ||||
| 
 | ||||
|       &:before { | ||||
|         display: none; | ||||
|       } | ||||
| 
 | ||||
|       &:after { | ||||
|         left: 0; | ||||
|         transition: all 0.2s ease; | ||||
|         background: var(--gray); | ||||
|         content: ""; | ||||
|         border-radius: 1em; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   & #dayIcon { | ||||
|     position: relative; | ||||
|     width: 20px; | ||||
|     height: 20px; | ||||
|     top: -1.5px; | ||||
|     margin: 0 7px; | ||||
|     fill: var(--gray); | ||||
|   } | ||||
| 
 | ||||
|   & #nightIcon { | ||||
|     position: relative; | ||||
|     width: 18px; | ||||
|     height: 18px; | ||||
|     top: -2px; | ||||
|     margin: 0 7px; | ||||
|     fill: var(--gray); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										99
									
								
								assets/syntax.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								assets/syntax.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | ||||
| /* Background */ .chroma { color: #f8f8f2; background-color: #282a36 } | ||||
| /* Other */ .chroma .x {  } | ||||
| /* Error */ .chroma .err {  } | ||||
| /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } | ||||
| /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; } | ||||
| /* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc } | ||||
| /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } | ||||
| /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } | ||||
| /* Keyword */ .chroma .k { color: #ff79c6 } | ||||
| /* KeywordConstant */ .chroma .kc { color: #ff79c6 } | ||||
| /* KeywordDeclaration */ .chroma .kd { color: #8be9fd; font-style: italic } | ||||
| /* KeywordNamespace */ .chroma .kn { color: #ff79c6 } | ||||
| /* KeywordPseudo */ .chroma .kp { color: #ff79c6 } | ||||
| /* KeywordReserved */ .chroma .kr { color: #ff79c6 } | ||||
| /* KeywordType */ .chroma .kt { color: #8be9fd } | ||||
| /* Name */ .chroma .n {  } | ||||
| /* NameAttribute */ .chroma .na { color: #50fa7b } | ||||
| /* NameBuiltin */ .chroma .nb { color: #8be9fd; font-style: italic } | ||||
| /* NameBuiltinPseudo */ .chroma .bp {  } | ||||
| /* NameClass */ .chroma .nc { color: #50fa7b } | ||||
| /* NameConstant */ .chroma .no {  } | ||||
| /* NameDecorator */ .chroma .nd {  } | ||||
| /* NameEntity */ .chroma .ni {  } | ||||
| /* NameException */ .chroma .ne {  } | ||||
| /* NameFunction */ .chroma .nf { color: #50fa7b } | ||||
| /* NameFunctionMagic */ .chroma .fm {  } | ||||
| /* NameLabel */ .chroma .nl { color: #8be9fd; font-style: italic } | ||||
| /* NameNamespace */ .chroma .nn {  } | ||||
| /* NameOther */ .chroma .nx {  } | ||||
| /* NameProperty */ .chroma .py {  } | ||||
| /* NameTag */ .chroma .nt { color: #ff79c6 } | ||||
| /* NameVariable */ .chroma .nv { color: #8be9fd; font-style: italic } | ||||
| /* NameVariableClass */ .chroma .vc { color: #8be9fd; font-style: italic } | ||||
| /* NameVariableGlobal */ .chroma .vg { color: #8be9fd; font-style: italic } | ||||
| /* NameVariableInstance */ .chroma .vi { color: #8be9fd; font-style: italic } | ||||
| /* NameVariableMagic */ .chroma .vm {  } | ||||
| /* Literal */ .chroma .l {  } | ||||
| /* LiteralDate */ .chroma .ld {  } | ||||
| /* LiteralString */ .chroma .s { color: #f1fa8c } | ||||
| /* LiteralStringAffix */ .chroma .sa { color: #f1fa8c } | ||||
| /* LiteralStringBacktick */ .chroma .sb { color: #f1fa8c } | ||||
| /* LiteralStringChar */ .chroma .sc { color: #f1fa8c } | ||||
| /* LiteralStringDelimiter */ .chroma .dl { color: #f1fa8c } | ||||
| /* LiteralStringDoc */ .chroma .sd { color: #f1fa8c } | ||||
| /* LiteralStringDouble */ .chroma .s2 { color: #f1fa8c } | ||||
| /* LiteralStringEscape */ .chroma .se { color: #f1fa8c } | ||||
| /* LiteralStringHeredoc */ .chroma .sh { color: #f1fa8c } | ||||
| /* LiteralStringInterpol */ .chroma .si { color: #f1fa8c } | ||||
| /* LiteralStringOther */ .chroma .sx { color: #f1fa8c } | ||||
| /* LiteralStringRegex */ .chroma .sr { color: #f1fa8c } | ||||
| /* LiteralStringSingle */ .chroma .s1 { color: #f1fa8c } | ||||
| /* LiteralStringSymbol */ .chroma .ss { color: #f1fa8c } | ||||
| /* LiteralNumber */ .chroma .m { color: #bd93f9 } | ||||
| /* LiteralNumberBin */ .chroma .mb { color: #bd93f9 } | ||||
| /* LiteralNumberFloat */ .chroma .mf { color: #bd93f9 } | ||||
| /* LiteralNumberHex */ .chroma .mh { color: #bd93f9 } | ||||
| /* LiteralNumberInteger */ .chroma .mi { color: #bd93f9 } | ||||
| /* LiteralNumberIntegerLong */ .chroma .il { color: #bd93f9 } | ||||
| /* LiteralNumberOct */ .chroma .mo { color: #bd93f9 } | ||||
| /* Operator */ .chroma .o { color: #ff79c6 } | ||||
| /* OperatorWord */ .chroma .ow { color: #ff79c6 } | ||||
| /* Punctuation */ .chroma .p {  } | ||||
| /* Comment */ .chroma .c { color: #6272a4 } | ||||
| /* CommentHashbang */ .chroma .ch { color: #6272a4 } | ||||
| /* CommentMultiline */ .chroma .cm { color: #6272a4 } | ||||
| /* CommentSingle */ .chroma .c1 { color: #6272a4 } | ||||
| /* CommentSpecial */ .chroma .cs { color: #6272a4 } | ||||
| /* CommentPreproc */ .chroma .cp { color: #ff79c6 } | ||||
| /* CommentPreprocFile */ .chroma .cpf { color: #ff79c6 } | ||||
| /* Generic */ .chroma .g {  } | ||||
| /* GenericDeleted */ .chroma .gd { color: #8b080b } | ||||
| /* GenericEmph */ .chroma .ge { text-decoration: underline } | ||||
| /* GenericError */ .chroma .gr {  } | ||||
| /* GenericHeading */ .chroma .gh { font-weight: bold } | ||||
| /* GenericInserted */ .chroma .gi { font-weight: bold } | ||||
| /* GenericOutput */ .chroma .go { color: #44475a } | ||||
| /* GenericPrompt */ .chroma .gp {  } | ||||
| /* GenericStrong */ .chroma .gs {  } | ||||
| /* GenericSubheading */ .chroma .gu { font-weight: bold } | ||||
| /* GenericTraceback */ .chroma .gt {  } | ||||
| /* GenericUnderline */ .chroma .gl { text-decoration: underline } | ||||
| /* TextWhitespace */ .chroma .w {  } | ||||
| 
 | ||||
| .lntd:first-of-type > .chroma { | ||||
|   padding-right: 0; | ||||
| } | ||||
| 
 | ||||
| .chroma code { | ||||
|   font-family: 'Fira Code' !important; | ||||
|   font-size: 0.85em; | ||||
|   line-height: 1em; | ||||
|   background: none; | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| .chroma { | ||||
|   border-radius: 3px; | ||||
|   margin: 0; | ||||
| } | ||||
							
								
								
									
										4
									
								
								config.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								config.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| baseURL = "https://quartz.jzhao.xyz/" | ||||
| languageCode = "en-us" | ||||
| googleAnalytics = "UA-148413215-1" | ||||
| pygmentsUseClasses = true | ||||
							
								
								
									
										0
									
								
								content/_index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/_index.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								content/moc/directory.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/moc/directory.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								content/notes/config.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/notes/config.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								content/notes/setup.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/notes/setup.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								content/notes/troubleshooting.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/notes/troubleshooting.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								content/notes/welcome.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								content/notes/welcome.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								data/config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								data/config.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| name: Quartz Example Page | ||||
| description: | ||||
|   Here is the page description. This is an example Quartz site that details installation, | ||||
|   setup, customization, and troubleshooting for Quartz itself. | ||||
| page_title: | ||||
|   Quartz Example Page | ||||
| links: | ||||
|   - link_name: twitter | ||||
|     link: https://twitter.com/_jzhao | ||||
|   - link_name: github | ||||
|     link: https://github.com/jackyzha0 | ||||
							
								
								
									
										11
									
								
								data/graphConfig.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								data/graphConfig.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| enableLegend: false | ||||
| enableDrag: true | ||||
| enableZoom: false | ||||
| base: | ||||
|   node: "#284b63" | ||||
|   activeNode: "#f28482" | ||||
|   inactiveNode: "#a8b3bd" | ||||
|   link: "#babdbf" | ||||
|   activeLink: "#5a7282" | ||||
| paths: | ||||
|   - /moc: "#4388cc" | ||||
							
								
								
									
										0
									
								
								layouts/404.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								layouts/404.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										10
									
								
								layouts/_default/baseof.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								layouts/_default/baseof.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| {{ block "head" . }} | ||||
| {{ end }} | ||||
| 
 | ||||
| <body> | ||||
| {{ block "main" . }} | ||||
| {{ end }} | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										24
									
								
								layouts/_default/single.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								layouts/_default/single.html
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										0
									
								
								layouts/index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										9
									
								
								layouts/partials/backlinks.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								layouts/partials/backlinks.html
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										16
									
								
								layouts/partials/darkmode.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								layouts/partials/darkmode.html
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										21
									
								
								layouts/partials/footer.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								layouts/partials/footer.html
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										218
									
								
								layouts/partials/graph.html
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										24
									
								
								layouts/partials/head.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								layouts/partials/head.html
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										0
									
								
								layouts/partials/header.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								layouts/partials/header.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										
											BIN
										
									
								
								static/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 31 KiB | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user