Merge branch 'hugo' into hugo
1 files deleted
1 files added
9 files modified
| | |
| | | - uses: actions/checkout@v2 |
| | | |
| | | - name: Build Link Index |
| | | uses: jackyzha0/hugo-obsidian@v2.3 |
| | | uses: jackyzha0/hugo-obsidian@v2.4 |
| | | with: |
| | | index: true |
| | | input: content |
| | |
| | | # Quartz |
| | | Simple second brain and digital garden. |
| | | Host your own second brain and digital garden for free. |
| | | |
| | | > “He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming |
| | | > “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming |
| | | |
| | | 🔗 Get Started: https://quartz.jzhao.xyz/ |
| | |
| | | left: 0; |
| | | top: 0; |
| | | width: 100vw; |
| | | height: 100vh; |
| | | height: 100%; |
| | | overflow: scroll; |
| | | display: none; |
| | | backdrop-filter: blur(4px); |
| | | -webkit-backdrop-filter: blur(4px); |
| | |
| | | border: 1px solid var(--outlinegray); |
| | | border-bottom: none; |
| | | |
| | | &:hover { |
| | | // normalize button props |
| | | font-family: inherit; |
| | | font-size: 100%; |
| | | line-height: 1.15; |
| | | margin: 0; |
| | | overflow: visible; |
| | | text-transform: none; |
| | | text-align: left; |
| | | background: var(--light); |
| | | outline: none; |
| | | |
| | | &:hover, &:focus { |
| | | background: rgba(180, 180, 180, 0.15); |
| | | } |
| | | |
| | |
| | | # 🌱 Quartz |
| | | ## v2.0 |
| | | |
| | | Simple second brain and [digital garden](https://jzhao.xyz/posts/digital-gardening). |
| | | |
| | | ## Why Quartz? |
| | | Hosting a public digital garden isn't easy. There are an overwhelming number of tutorials, resources, and guides for tools like [Notion](https://www.notion.so/), [Roam](https://roamresearch.com/), and [Obsidian](https://obsidian.md/), yet none of them have super easy to use *free* tools to publish that garden to the world. |
| | | |
| | | I've personally found that |
| | | 1. It's nice to access notes from anywhere |
| | | 2. Having a public digital garden invites open conversations |
| | | 3. It makes keeping personal notes and knowledge *playful and fun* |
| | | |
| | | > “He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming |
| | | |
| | | I was really inspired by [Bianca](https://garden.bianca.digital/) and [Joel](https://joelhooks.com/digital-garden)'s digital gardens and wanted to try making my own. |
| | | |
| | | **The goal of Quartz is to make hosting your own public digital garden free and simple.** You don't even need your own website. Quartz does all of that for you and gives your own little corner of the internet. |
| | | --- |
| | | title: 🪴 Quartz v2.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 `/` |
| | | 2. Beautiful, out-of-the-box website creation and deployment |
| | | 3. Display for backlinks of each note |
| | | 4. A customizable graph view |
| | | 5. Endlessly powerful page and theme customization |
| | | |
| | | ## Get Started |
| | | The entire Quartz documentation is fully hosted using Quartz! To get started, let's visit the main directory. |
| | | > 📚 [Setup your own digital garden using Quartz](notes/setup.md) |
| | | |
| | | 👉 [Directory](moc/directory.md) |
| | | Not convinced yet? Look at some [community digital gardens](moc/showcase) built with Quartz, or read about [why I made Quartz](notes/philosophy.md) to begin with! |
| | | |
| | | ## Troubleshooting |
| | | - 🚧 [Troubleshooting and FAQ](notes/troubleshooting.md) |
| | | - 🐛 [Submit an Issue](https://github.com/jackyzha0/quartz/issues) |
| | |
| | | - [Shihyu's PKM](https://shihyuho.github.io/pkm/) |
| | | - [Chloe's Garden](https://garden.chloeabrasada.online/) |
| | | - [SlRvb's Site](https://slrvb.github.io/Site/) |
| | | - [Course notes for Information Technology Advanced Theory](https://a2itnotes.github.io/quartz/) |
| | | |
| | | If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/hugo/content/moc/showcase.md)! |
| | |
| | | |
| | | Now that your Quartz is live, let's figure out how to make Quartz really *yours*! |
| | | |
| | | 🎨 [Customizing Quarts](notes/config.md) |
| | | 🎨 [Customizing Quartz](notes/config.md) |
| | | |
| | | Having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md). |
| | |
| | | ``` |
| | | |
| | | `ignoreFiles` supports the use of Regular Expressions (RegEx) so you can ignore patterns as well (e.g. ignoring all `.png`s by doing `\\.png$`). |
| | | To ignore a specific file, you can also add the tag `draft: true` to the frontmatter of a note. |
| | | |
| | | ```markdown |
| | | --- |
| | | title: Some Private Note |
| | | draft: true |
| | | --- |
| | | ... |
| | | ``` |
| | | |
| | | More details in [Hugo's documentation](https://gohugo.io/getting-started/configuration/#ignore-content-and-data-files-when-rendering). |
| | | |
| New file |
| | |
| | | --- |
| | | title: Quartz Philosophy |
| | | --- |
| | | |
| | | > “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming |
| | | |
| | | ## Why Quartz? |
| | | Hosting a public digital garden isn't easy. There are an overwhelming number of tutorials, resources, and guides for tools like [Notion](https://www.notion.so/), [Roam](https://roamresearch.com/), and [Obsidian](https://obsidian.md/), yet none of them have super easy to use *free* tools to publish that garden to the world. |
| | | |
| | | I've personally found that |
| | | 1. It's nice to access notes from anywhere |
| | | 2. Having a public digital garden invites open conversations |
| | | 3. It makes keeping personal notes and knowledge *playful and fun* |
| | | |
| | | I was really inspired by [Bianca](https://garden.bianca.digital/) and [Joel](https://joelhooks.com/digital-garden)'s digital gardens and wanted to try making my own. |
| | | |
| | | **The goal of Quartz is to make hosting your own public digital garden free and simple.** You don't even need your own website. Quartz does all of that for you and gives your own little corner of the internet. |
| | |
| | | {{partial "footer.html" .}} |
| | | </div> |
| | | </body> |
| | | |
| | | </html> |
| | | |
| | |
| | | <div id="search-container"> |
| | | <div> |
| | | <div id="search-space"> |
| | | <input autocomplete="off" id="search-bar" name="search" type="text" aria-label="Search" placeholder="Search for something..."> |
| | | <div id="results-container"> |
| | | </div> |
| | |
| | | </script> |
| | | <script> |
| | | const contentIndex = new FlexSearch.Worker({ |
| | | tokenize: "strict", |
| | | charset: "latin:advanced", |
| | | context: true, |
| | | depth: 3, |
| | | cache: 10, |
| | | tokenize: "reverse", |
| | | charset: "latin:extra", |
| | | suggest: true, |
| | | cache: 10, |
| | | }) |
| | | |
| | | const scrapedContent = {{$.Site.Data.contentIndex}} |
| | |
| | | contentIndex.add(key, value.content) |
| | | } |
| | | |
| | | const stopwords = ['i','me','my','myself','we','our','ours','ourselves','you','your','yours','yourself','yourselves','he','him','his','himself','she','her','hers','herself','it','its','itself','they','them','their','theirs','themselves','what','which','who','whom','this','that','these','those','am','is','are','was','were','be','been','being','have','has','had','having','do','does','did','doing','a','an','the','and','but','if','or','because','as','until','while','of','at','by','for','with','about','against','between','into','through','during','before','after','above','below','to','from','up','down','in','out','on','off','over','under','again','further','then','once','here','there','when','where','why','how','all','any','both','each','few','more','most','other','some','such','no','nor','not','only','own','same','so','than','too','very','s','t','can','will','just','don','should','now'] |
| | | const highlight = (content, term) => { |
| | | const highlightWindow = 15 |
| | | const highlightWindow = 20 |
| | | const tokenizedTerm = term.split(/\s+/).filter(t => t !== "") |
| | | const splitText = content.split(/\s+/).filter(t => t !== "") |
| | | const includesCheck = (token) => tokenizedTerm.some(term => token.toLowerCase().includes(term.toLowerCase())) |
| | | const includesCheck = (token) => tokenizedTerm.some(term => token.toLowerCase().startsWith(term.toLowerCase())) |
| | | |
| | | const occurrencesIndices = splitText |
| | | .map(includesCheck) |
| | |
| | | for (let i = 0; i < Math.max(occurrencesIndices.length - highlightWindow, 0); i++) { |
| | | const window = occurrencesIndices.slice(i, i + highlightWindow) |
| | | const windowSum = window.reduce((total, cur) => total + cur, 0) |
| | | if (windowSum > bestSum) { |
| | | if (windowSum >= bestSum) { |
| | | bestSum = windowSum |
| | | bestIndex = i |
| | | } |
| | |
| | | } |
| | | |
| | | const resultToHTML = ({url, title, content, term}) => { |
| | | const md = content.split("---")[2] |
| | | const text = removeMarkdown(md) |
| | | const text = removeMarkdown(content) |
| | | const resultTitle = highlight(title, term) |
| | | const resultText = highlight(text, term) |
| | | return `<div class="result-card" id="${url}"> |
| | | return `<button class="result-card" id="${url}"> |
| | | <h3>${resultTitle}</h3> |
| | | <p>${resultText}</p> |
| | | </div>` |
| | | </button>` |
| | | } |
| | | |
| | | const redir = (id, term) => { |
| | | window.location.href = "{{.Site.BaseURL}}" + `${id}#:~:text=${encodeURIComponent(term)}` |
| | | } |
| | | |
| | | const source = document.getElementById('search-bar') |
| | | const results = document.getElementById("results-container") |
| | | let term |
| | | source.addEventListener("keyup", (e) => { |
| | | if (e.key === "Enter") { |
| | | const anchor = document.getElementsByClassName("result-card")[0] |
| | | redir(anchor.id, term) |
| | | } |
| | | }) |
| | | source.addEventListener('input', (e) => { |
| | | const term = e.target.value |
| | | term = e.target.value |
| | | contentIndex.search(term, { |
| | | limit: 5, |
| | | depth: 3, |
| | | limit: 15, |
| | | suggest: true, |
| | | }).then(searchResults => { |
| | | const resultIds = [...new Set(searchResults)] |
| | |
| | | .join("\n") |
| | | const anchors = document.getElementsByClassName("result-card"); |
| | | [...anchors].forEach(anchor => { |
| | | anchor.onclick = () => { |
| | | window.location.href = `${anchor.id}#:~:text=${encodeURIComponent(term)}` |
| | | } |
| | | anchor.onclick = () => redir(anchor.id, term) |
| | | }) |
| | | } |
| | | }) |
| | |
| | | searchButton.addEventListener('keydown', (evt) => { |
| | | openSearch() |
| | | }) |
| | | searchContainer.addEventListener('click', (evt) => { |
| | | closeSearch() |
| | | }) |
| | | document.getElementById("search-space").addEventListener('click', (evt) => { |
| | | evt.stopPropagation() |
| | | }) |
| | | }) |
| | | |
| | | </script> |