feat: dynamically fetch indices
| | |
| | | - uses: actions/checkout@v2 |
| | | |
| | | - name: Build Link Index |
| | | uses: jackyzha0/hugo-obsidian@v2.7 |
| | | uses: jackyzha0/hugo-obsidian@v2.8 |
| | | with: |
| | | index: true |
| | | input: content |
| | |
| | | resources |
| | | .idea |
| | | content/.obsidian |
| | | data/linkIndex.yaml |
| | | data/contentIndex.yaml |
| | | static/linkIndex.json |
| | | static/contentIndex.json |
| | |
| | | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
| | | |
| | | serve: ## serve |
| | | hugo-obsidian -input=content -output=data -index -root=. && hugo server |
| | | hugo-obsidian -input=content -output=static -index -root=. && hugo server |
| | |
| | | --- |
| | | title: 🪴 Quartz 3 |
| | | title: 🪴 Quartz 3.1 |
| | | --- |
| | | Host your second brain and [digital garden](https://jzhao.xyz/posts/digital-gardening) for free. Quartz features |
| | | 1. Extremely fast full-text search by pressing `/` |
| | |
| | | Here is the page description. This is an example Quartz site that details installation, |
| | | setup, customization, and troubleshooting for Quartz itself. |
| | | page_title: |
| | | "🪴 Quartz 3" |
| | | "🪴 Quartz 3.1" |
| | | links: |
| | | - link_name: Twitter |
| | | link: https://twitter.com/_jzhao |
| | |
| | | {{$url := urls.Parse .Site.BaseURL }} |
| | | {{$host := strings.TrimRight "/" $url.Path }} |
| | | {{$curPage := strings.TrimPrefix $host (strings.TrimRight "/" .Page.RelPermalink) }} |
| | | {{$inbound := index $.Site.Data.linkIndex.index.backlinks $curPage}} |
| | | {{$contentTable := $.Site.Data.contentIndex}} |
| | | {{$linkIndex := getJSON "/static/linkIndex.json"}} |
| | | {{$inbound := index $linkIndex.index.backlinks $curPage}} |
| | | {{$contentTable := getJSON "/static/contentIndex.json"}} |
| | | {{if $inbound}} |
| | | {{$cleanedInbound := apply (apply $inbound "index" "." "source") "replace" "." " " "-"}} |
| | | {{- range $cleanedInbound | uniq -}} |
| | |
| | | } |
| | | </style> |
| | | <script> |
| | | async function run() { |
| | | const { index, links, content } = await fetchData() |
| | | const curPage = {{ strings.TrimRight "/" .Page.Permalink }}.replace({{strings.TrimRight "/" .Site.BaseURL }}, "") |
| | | const pathColors = {{$.Site.Data.graphConfig.paths}} |
| | | let depth = {{$.Site.Data.graphConfig.depth}} |
| | |
| | | .attr("x1", d => d.source.x) |
| | | .attr("y1", d => d.source.y) |
| | | .attr("x2", d => d.target.x) |
| | | .attr("y2", d => d.target.y); |
| | | .attr("y2", d => d.target.y) |
| | | node |
| | | .attr("cx", d => d.x) |
| | | .attr("cy", d => d.y); |
| | | .attr("cy", d => d.y) |
| | | labels |
| | | .attr("x", d => d.x) |
| | | .attr("y", d => d.y); |
| | | .attr("y", d => d.y) |
| | | }); |
| | | } |
| | | |
| | | run() |
| | | </script> |
| | |
| | | |
| | | <!-- Preload page vars --> |
| | | <script> |
| | | const content = {{$.Site.Data.contentIndex}} |
| | | const index = {{$.Site.Data.linkIndex.index}} |
| | | const links = {{$.Site.Data.linkIndex.links}} |
| | | const fetchData = async () => { |
| | | const promises = [ |
| | | fetch("/linkIndex.json") |
| | | .then(data => data.json()) |
| | | .then(data => ({ |
| | | index: data.index, |
| | | links: data.links, |
| | | })), |
| | | fetch("/contentIndex.json") |
| | | .then(data => data.json()), |
| | | ] |
| | | const [{index, links}, content] = await Promise.all(promises) |
| | | return ({ |
| | | index, |
| | | links, |
| | | content, |
| | | }) |
| | | } |
| | | </script> |
| | | </head> |
| | | {{ template "_internal/google_analytics.html" . }} |
| | |
| | | {{if $.Site.Data.config.enableLinkPreview}} |
| | | <script> |
| | | async function run() { |
| | | const {content} = await fetchData() |
| | | function htmlToElement(html) { |
| | | const template = document.createElement('template') |
| | | html = html.trim() |
| | |
| | | document.addEventListener("DOMContentLoaded", () => { |
| | | [...document.getElementsByClassName("internal-link")] |
| | | .forEach(li => { |
| | | console.log(li.dataset.src.replace(pathRegex, '')) |
| | | const linkDest = content[li.dataset.src.replace(pathRegex, '')] |
| | | if (linkDest) { |
| | | const popoverElement = `<div class="popover"> |
| | |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | run() |
| | | </script> |
| | | {{end}} |
| | |
| | | }; |
| | | </script> |
| | | <script> |
| | | async function run() { |
| | | const contentIndex = new FlexSearch.Document({ |
| | | cache: true, |
| | | charset: "latin:extra", |
| | |
| | | } |
| | | }) |
| | | |
| | | const { content } = await fetchData() |
| | | for (const [key, value] of Object.entries(content)) { |
| | | contentIndex.add({ |
| | | id: key, |
| | |
| | | window.location.href = "{{.Site.BaseURL}}" + `${id}#:~:text=${encodeURIComponent(term)}` |
| | | } |
| | | |
| | | const fetch = id => ({ |
| | | const formatForDisplay = id => ({ |
| | | id, |
| | | url: id, |
| | | title: content[id].title, |
| | |
| | | } |
| | | } |
| | | const allIds = new Set([...getByField('title'), ...getByField('content')]) |
| | | const finalResults = [...allIds].map(fetch) |
| | | const finalResults = [...allIds].map(formatForDisplay) |
| | | |
| | | // display |
| | | if (finalResults.length === 0) { |
| | |
| | | |
| | | |
| | | const searchContainer = document.getElementById("search-container") |
| | | |
| | | function openSearch() { |
| | | if (searchContainer.style.display === "none" || searchContainer.style.display === "") { |
| | | source.value = "" |
| | |
| | | evt.stopPropagation() |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | run() |
| | | </script> |